Essential Qt 第三章 搜尋對話框

    對於大多數window7/10等win用戶來說,windows自帶的記事本程序再熟悉不過了,他提供了最基本的文本編輯功能,接下來幾章我們將製作一個類似的程序,整個程序相對(之前幾章的例子)比較大,所以我們先從他的一個對話框開始。
    

    這是一個查詢對話框,和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上可以找到答案
發佈了92 篇原創文章 · 獲贊 19 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章