接上文:編寫Qt Designer自定義控件(一)——如何創建並使用Qt自定義控件
既然是控件,就應該有界面,默認生成的控件類只是一個繼承了QWidget的類,如下:
#ifndef LOGLATEDIT_H
#define LOGLATEDIT_H
#include <QWidget>
class LogLatEdit : public QWidget
{
Q_OBJECT
public:
LogLatEdit(QWidget *parent = 0);
};
#endif
我們需要的是如下的控件組合:

該控件在輸入浮點型模式下,是上面那樣,直接輸入以度為單位的浮點數即可,如果經緯度信息不是以度為單位的,此時自己換算的話非常麻煩,因此可以切換為度分秒的輸入模式,也就是下面哪種樣子。為此,我們需要添加一個LineEidt,兩個SpinBox和一個DoubleSpinBox以及一些Label控件。
為了簡單起見,我不想自己手動去寫這些界面相關的代碼,為此我們可以先刪掉默認生成的loglatedit.h和loglatedit.cpp文件,這樣我們就可以重新使用LogLatEdit這個名稱重新新建一個ui類了。右鍵工程,選擇“添加新文件”,使用Qt下的“Qt設計師界面類”模板,創建一個ui類,如下圖所示:

這個界面類,我們重新命名為我們需要的控件名稱LogLatEdit,之后編輯ui文件,調整QWidget的大小,然后繪制控件,如圖:
這里使用了HorizontalLayout控件對控件組合進行分組,為了演示方便,此處將二者拖放開來,最終的控件,實際上是兩個水平布局疊加在一起,每次只有一個控件組合可見。
當然另一個做法也是可行的,那就是不要刪除最初默認生成的loglatedit文件,而是把這個新建的ui類命名為別的名字,比如test,在繪制好控件之后,編譯一下,然后找到Moc生成的ui_test.h文件,打開該文件,我們把相應的代碼拷貝到我們的LogLatEdit控件類中去,然后做適當的修改,比如設定兩個控件組合的位置及可見性,以及控件容器QWidget的大小等。這里為了把所有相關的代碼都放在一起,便於讀者測試,使用的就是這種方式。
使用ui類作的方式比較方便,所有與界面相關的處理都可以在窗體設計器中完成,並且界面與代碼分離,這種代碼管理模式邏輯清晰,便於管理。不過使用ui類時,如果我們的ui類名稱不是默認的LogLatEdit,則需要修改一下插件類中創建插件的代碼,主要是修改loglateditplugin.cpp文件里createWidget方法中返回的控件對象。
經過修改之后我們的經緯度控件的代碼如下:
#ifndef LOGLATEDIT_H
#define LOGLATEDIT_H
#include <QWidget>
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QDoubleSpinBox>
#include <QtGui/QHBoxLayout>
#include <QtGui/QHeaderView>
#include <QtGui/QLabel>
#include <QtGui/QLineEdit>
#include <QtGui/QSpacerItem>
#include <QtGui/QSpinBox>
#include <QtGui/QWidget>
class LogLatEdit : public QWidget
{
Q_OBJECT
public:
LogLatEdit(QWidget *parent = 0);
private:
QWidget *horizontalLayoutWidget;
QHBoxLayout *horizontalLayout;
QSpinBox *spinBox;
QLabel *label_7;
QSpinBox *spinBox_2;
QLabel *label_8;
QDoubleSpinBox *doubleSpinBox;
QLabel *label_9;
QWidget *horizontalLayoutWidget_2;
QHBoxLayout *horizontalLayout_2;
QLineEdit *lineEdit;
QLabel *label_6;
QSpacerItem *horizontalSpacer;
QSpacerItem *horizontalSpacer_2;
};
#endif
源文件:
#include "loglatedit.h"
LogLatEdit::LogLatEdit(QWidget *parent) :
QWidget(parent)
{
this->resize(160, 22);
this->setMinimumSize(QSize(160,22)); //限定控件的大小
this->setMaximumSize(QSize(200,22));
horizontalLayoutWidget = new QWidget(this);
horizontalLayoutWidget->setObjectName(QString::fromUtf8("horizontalLayoutWidget"));
horizontalLayoutWidget->setGeometry(QRect(0, 0, 160, 22));
horizontalLayout = new QHBoxLayout(horizontalLayoutWidget);
horizontalLayout->setSpacing(1);
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
horizontalLayout->setContentsMargins(0, 0, 0, 0);
spinBox = new QSpinBox(horizontalLayoutWidget);
spinBox->setObjectName(QString::fromUtf8("spinBox"));
spinBox->setMinimumSize(QSize(35, 20));
spinBox->setMaximumSize(QSize(35, 20));
spinBox->setMaximum(90);
horizontalLayout->addWidget(spinBox);
label_7 = new QLabel(horizontalLayoutWidget);
label_7->setObjectName(QString::fromUtf8("label_7"));
QSizePolicy sizePolicy(QSizePolicy::Fixed, QSizePolicy::Preferred);
sizePolicy.setHorizontalStretch(0);
sizePolicy.setVerticalStretch(0);
sizePolicy.setHeightForWidth(label_7->sizePolicy().hasHeightForWidth());
label_7->setSizePolicy(sizePolicy);
label_7->setMinimumSize(QSize(3, 20));
label_7->setSizeIncrement(QSize(1, 0));
horizontalLayout->addWidget(label_7);
horizontalSpacer = new QSpacerItem(0, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout->addItem(horizontalSpacer);
spinBox_2 = new QSpinBox(horizontalLayoutWidget);
spinBox_2->setObjectName(QString::fromUtf8("spinBox_2"));
spinBox_2->setMinimumSize(QSize(35, 20));
spinBox_2->setMaximumSize(QSize(35, 20));
spinBox_2->setMaximum(90);
horizontalLayout->addWidget(spinBox_2);
label_8 = new QLabel(horizontalLayoutWidget);
label_8->setObjectName(QString::fromUtf8("label_8"));
sizePolicy.setHeightForWidth(label_8->sizePolicy().hasHeightForWidth());
label_8->setSizePolicy(sizePolicy);
label_8->setMinimumSize(QSize(3, 20));
label_8->setSizeIncrement(QSize(1, 0));
horizontalLayout->addWidget(label_8);
horizontalSpacer_2 = new QSpacerItem(0, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout->addItem(horizontalSpacer_2);
doubleSpinBox = new QDoubleSpinBox(horizontalLayoutWidget);
doubleSpinBox->setObjectName(QString::fromUtf8("doubleSpinBox"));
doubleSpinBox->setMinimumSize(QSize(66, 20));
doubleSpinBox->setMaximumSize(QSize(66, 20));
doubleSpinBox->setDecimals(4);
doubleSpinBox->setMaximum(90);
horizontalLayout->addWidget(doubleSpinBox);
label_9 = new QLabel(horizontalLayoutWidget);
label_9->setObjectName(QString::fromUtf8("label_9"));
sizePolicy.setHeightForWidth(label_9->sizePolicy().hasHeightForWidth());
label_9->setSizePolicy(sizePolicy);
label_9->setMinimumSize(QSize(3, 20));
label_9->setSizeIncrement(QSize(1, 0));
horizontalLayout->addWidget(label_9);
horizontalLayoutWidget_2 = new QWidget(this);
horizontalLayoutWidget_2->setObjectName(QString::fromUtf8("horizontalLayoutWidget_2"));
horizontalLayoutWidget_2->setGeometry(QRect(0, 0, 160, 22));
horizontalLayout_2 = new QHBoxLayout(horizontalLayoutWidget_2);
horizontalLayout_2->setSpacing(1);
horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
horizontalLayout_2->setContentsMargins(0, 0, 0, 0);
lineEdit = new QLineEdit(horizontalLayoutWidget_2);
lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
lineEdit->setInputMethodHints(Qt::ImhDigitsOnly|Qt::ImhFormattedNumbersOnly);
horizontalLayout_2->addWidget(lineEdit);
label_6 = new QLabel(horizontalLayoutWidget_2);
label_6->setObjectName(QString::fromUtf8("label_6"));
horizontalLayout_2->addWidget(label_6);
label_7->setText(QApplication::translate("LogLatEdit", "\302\260", 0, QApplication::UnicodeUTF8));
label_8->setText(QApplication::translate("LogLatEdit", "\342\200\262", 0, QApplication::UnicodeUTF8));
label_9->setText(QApplication::translate("LogLatEdit", "\342\200\263", 0, QApplication::UnicodeUTF8));
label_6->setText(QApplication::translate("LogLatEdit", "\302\260", 0, QApplication::UnicodeUTF8));
horizontalLayoutWidget_2->setVisible(false);
QMetaObject::connectSlotsByName(this);
}
至此,界面相關的事情就做完了,后面我們需要給這個控件添加兩個屬性,一個輸入模式屬性,更改這個屬性時,我們的控件可以在兩種輸入模式下切換,另一個屬性就是經緯度值,我們要使其可以設置和返回經緯度值。
未完,待續...
