這是一個查詢對話框,和windows記事本的對話框很相似,這個對話框中除了前面章節已經介紹過的QLabel和QPushButton外,還使用了
QLineEdit 這是一個基於行的文本編輯器,提供了基礎的文本編輯功能
QCheckBox 這個是單選框,功能和他的名字一樣。
另外一個就是QDialog,對話框在圖像編程中最常見的窗體,很多程序都會利用對話框和用戶進行信息交互,在QT中,大多數對話框都會繼承自QDialog.
要完成這個對話框的製作,我們首先分兩步,第一步,製作界面佈局,第二步,實現他的功能
這個對話框被暫時命名爲FindDialog,首先是他的頭文件代碼
#include<QDialog> //註釋1
#include<QLineEdit>
#include<QCheckBox>
#include<QPushButton>
#include<QLabel>
class FindDialog:public QDialog
{
private:
QLabel* Title_Label;
QLineEdit* FindString_LineEdit;
QPushButton* Find_PushButton;
QPushButton* Close_PushButton;
QCheckBox* MatchCase_CheckBox;
QCheckBox* GoBack_CheckBox;
public:
FindDialog(QWidget* parents = 0); //註釋2
};
註釋1 這裏包含了各控件所需要的頭文件,其中QDialog是作爲QFindDialog的基類
註釋2 這是構造函數,參數是一個QWidget的指針,前面說過Qt中窗體部件都會繼承自QWidget,這個參數默作用是設置這個窗體的父窗體,如果值使用默認值,就說明該窗體沒有父窗體。
然後是FindDialog.cxx文件
#include<QHBoxLayout>
#include<QVBoxLayout>
#include"FindDialog.h"
FindDialog::FindDialog(QWidget* parents):QDialog(parents) //註釋1
{
Title_Label = new QLabel(tr("查詢內容")); //註釋2
FindString_LineEdit = new QLineEdit;
Find_PushButton = new QPushButton(tr("查詢"));
Close_PushButton = new QPushButton(tr("取消"));
MatchCase_CheckBox = new QCheckBox(tr("區分大小寫"));
GoBack_CheckBox = new QCheckBox(tr("向後查詢"));
QHBoxLayout* String_Layout = new QHBoxLayout; //註釋3
String_Layout->addWidget(Title_Label);
String_Layout->addWidget(FindString_LineEdit);
QVBoxLayout* Case_Layout = new QVBoxLayout;
Case_Layout->addLayout(String_Layout);
Case_Layout->addWidget(MatchCase_CheckBox);
Case_Layout->addWidget(GoBack_CheckBox);
QVBoxLayout* PushButton_Layout = new QVBoxLayout;
PushButton_Layout->addWidget(Find_PushButton);
PushButton_Layout->addWidget(Close_PushButton);
PushButton_Layout->addStretch();
QHBoxLayout* Main_Layout = new QHBoxLayout;
Main_Layout->addLayout(Case_Layout);
Main_Layout->addLayout(PushButton_Layout);
setLayout(Main_Layout);
Main_Layout->setSizeConstraint(QLayout::SetFixedSize); //註釋4
Find_PushButton->setDefault(true); //註釋5
Find_PushButton->setEnabled(false);
setWindowTitle(tr("查詢"));
}
註釋1 在構造函數中調用基類的構造函數,參數parent的類型是QWidget*,傳遞的參數只要是繼承自QWidget的窗體都可以作爲參數,即這個窗體的父窗體。參考C++中公有繼承的is-a關係
註釋2 創建我們需要的各個窗體部件
註釋3 使用佈局管理器來安裝各個窗體部件,代碼比較多但其實就是佈局管理器的各種嵌套,具體步驟:
a.把QLabel和QLineEdit放入一個QHBoxLayout(既String_Layout)
b.把上面的String_Layout和兩個QCheckBox放入一個QVBoxLayout(即Case_Layout)
c.把2個QPushButton放入一個QVBoxLayout(即PushButton_Layout),然後在下面價格彈簧addStretch()
d.把Case_Layout和PushButton_Layout放入一個QHBoxLayout(即Main_Layout)
當然就像前面佈局一章中演示的那樣,你也可以嘗試用其他的嵌套來完成這個界面佈局
註釋4 這個函數的作用是限定對話框的大小,對於Qt各窗體部件,如果你沒有設置他大小的情況下,都會有一
個Qt認爲最合適的大小,事實上這個大小大多數情況下都符合我們的要求,所以用這個函數使得對話框
的大小固定爲默認值,即Qt認爲最適合的值,這個函數通常用於窗體需要禁止拉伸的情況下
註釋5 這裏調用了幾個窗體的成員函數
setDefault()函數,用於設置這個按鈕爲默認按鈕,默認按鈕的意義在於,當你的當前窗體爲對話框
的時候,按下回車建,程序將認爲你點擊了該按鈕
setEnabled()函數,設置查詢按鈕不可用,當QLineEdit裏的內容爲空的時候,該按鈕不可用
最後我們要調用這個FindDialog類,來生成一個具體的對象,我們可以編寫一個簡單的Main.cxx來實現
#include<QApplication>
#include"FindDialog.h"
int main(int argc , char** argv)
{
QApplication app(argc,argv);
FindDialog A;
A.show();
app.exec();
}
注意這裏使用了FindDialog A而不是FindDialog* A = new FindDialog,這當然是爲了內存的考慮。
現在我們完成了第一步,界面的製作,然後我們需要實現他的具體功能
我們先要添加2個功能,第一,點擊取消按鈕的時候,這個對話框能夠關閉,第二,當QLineEdit裏有內容的時候,查詢按鈕可用,需要實現這2個功能,需要用到信號與槽
首先看下FindDialog.h文件的改動
#include<QDialog>
#include<QLineEdit>
#include<QCheckBox>
#include<QPushButton>
#include<QLabel>
class FindDialog:public QDialog
{
Q_OBJECT //註釋1
private:
QLabel* Title_Label;
QLineEdit* FindString_LineEdit;
QPushButton* Find_PushButton;
QPushButton* Close_PushButton;
QCheckBox* MatchCase_CheckBox;
QCheckBox* GoBack_CheckBox;
public:
FindDialog(QWidget* parents = 0);
public slots:
void Find_PushButtonIsEnable(const QString& str); //註釋2
};
註釋1 這裏添加了一行Q_OBJECT,這是一個Qt定義的宏,如果一個類需要使用信號與槽,就必須添加這個宏
註釋2 這裏添加了一個共有槽,用於設置查詢按鈕是否可用,這裏注意的是槽有私有和公有的區別,共有槽在
類外也可以鏈接(使用),而私有槽只能用於類的內部,這個和私有/公有成員函數是一致的
然後在看下FindDialog.cxx文件的改動
#include<QHBoxLayout>
#include<QVBoxLayout>
#include"FindDialog.h"
FindDialog::FindDialog(QWidget* parents):QDialog(parents)
{
Title_Label = new QLabel(tr("查詢內容"));
FindString_LineEdit = new QLineEdit;
Find_PushButton = new QPushButton(tr("查詢"));
Close_PushButton = new QPushButton(tr("取消"));
MatchCase_CheckBox = new QCheckBox(tr("區分大小寫"));
GoBack_CheckBox = new QCheckBox(tr("向後查詢"));
QHBoxLayout* String_Layout = new QHBoxLayout;
String_Layout->addWidget(Title_Label);
String_Layout->addWidget(FindString_LineEdit);
QVBoxLayout* Case_Layout = new QVBoxLayout;
Case_Layout->addLayout(String_Layout);
Case_Layout->addWidget(MatchCase_CheckBox);
Case_Layout->addWidget(GoBack_CheckBox);
QVBoxLayout* PushButton_Layout = new QVBoxLayout;
PushButton_Layout->addWidget(Find_PushButton);
PushButton_Layout->addWidget(Close_PushButton);
PushButton_Layout->addStretch();
QHBoxLayout* Main_Layout = new QHBoxLayout;
Main_Layout->addLayout(Case_Layout);
Main_Layout->addLayout(PushButton_Layout);
setLayout(Main_Layout);
Main_Layout->setSizeConstraint(QLayout::SetFixedSize);
Find_PushButton->setDefault(true);
Find_PushButton->setEnabled(false);
connect(FindString_LineEdit,SIGNAL(textChanged(const QString&)),this,SLOT(Find_PushButtonIsEnable(const QString&)));
connect(Close_PushButton,SIGNAL(clicked()),this,SLOT(close())); //註釋1
setWindowTitle(tr("查詢"));
}
void FindDialog::Find_PushButtonIsEnable(const QString& str) //註釋2
{
Find_PushButton->setEnabled(!str.isEmpty());
}
註釋1 這裏進行了2個鏈接,點擊關閉按鈕,觸發clicked()信號,鏈接到這個類(對話框)的close()槽,這
個FindDialog類繼承自QDialog,close()是QDialog的一個共有槽,用於關閉自身
對於QLineEdit,有一個信號textChanged(const QString&),每當編輯行的內容發生改變的時候就會
發射這個信號,我們在FindDialog中自定義了一個公有槽,和這個信號鏈接
註釋2 這是自定義的共有槽,當然,這個函數也完全可以當初普通的公有成員函數來使用,信號會把編輯
行的內容以QString的形式傳遞過來,通過判斷QString是否爲空就可以設置查詢按鈕是否可用
我們運行這個程序後可以實現2個功能,第一,往編輯行裏面寫一些東西,查詢按鈕就會變爲可用,刪除掉編輯行裏的內查詢按鈕又會便的不可用,第二,點擊取消按鈕的時候這個窗體會關閉,即程序結束
留下的問題
a.這個對話框還有很多功能沒有做上去,當然,這個需要和記事本程序一起完成,所以其他的功能留到
後面和記事本完成
b.可能你已經發現這個程序不再想以前那樣,“一點點內存泄漏關係不大”,內存是否泄漏很重要,前面的
章節之所以演示一些錯誤的做法是希望你不要犯類似的問題,具體的情況很快就會講述
c.如果你熟悉windows的記事本程序,你會發現,他的對話框和這個有些不同,差不多應該是這個樣子
這裏查詢方向使用了QGroupBox和QRadioBox的組合,關於這兩個窗體部件使用可以參加assistant,然
後寫一個這樣的程序
d.使用assistans,這很重要,非常的重要,Qt的內容太多,不可能記住所有,任何教材也只能介紹很少一
部分內容,當遇到問題時,如QGroupBox和QRadioBox的使用,assistant上可以找到答案