用Qt Creator開發Windows的簡單計算機的程式

  • 50929
  • 0

用Qt Creator開發Windows的簡單計算機的程式

因為這次的目的也是為了確認透過Qt來開發WinCE的程式

所以請確認自己的環境是否有設定完成,這部分的程序請看http://www.dotblogs.com.tw/pin0513/archive/2010/01/08/12918.aspx

以方便後續將Qt專案編譯成VC++的程式

 

你可以先安裝Qt Creater

安裝完以後,在程式集中你就可以選擇Qt Creator開始執行

 

先new一個Qt專案,因為要開發有畫面的程式,所以先選擇Gui

11

下一步:設定專案名稱與位置

12

接著設定函式庫,先用預設就好

設定專案的類別名稱,這邊你就可以自行命名了!

13 

建好後,精靈會幫你建好方案檔以及相關的資源資料夾

14

在這邊比較重要的幾個檔會是:

Forms(應用程式ui),你也可以不用有這個檔,你可以在程式中宣告物件再定義其layout也是可以的。

  • [Application Name].ui - the user interface file created with Qt Designer

Headers(應用程式類別標頭檔)

  • [Application Name].h - the definition file for the [Application Name] class,

Resources(程式碼檔):至少會有下列兩個檔

  • main.cpp - the file containing a main() function, with an instance of [Application Name]
    • 通常不會更改什麼資料,這邊的程式會建立一個application的實例
  • [Application Name].cpp - the implementation file for the [Application Name] class
    • 注意:Subclassing 技巧可以讓你寫的widget程式再利用(若建立的是widget專案,則自動subclassing到main window之下,這邊僅是Win App

首先我們通常在IDE的環境中,我們可能會先拉一些控件(qt裡面稱為widget)。

Qt也提供了Designer來提供VS使用Qt專案的控件!叫Qt設計家

你只要點擊.ui檔開啟即可。 長的如下圖,左邊是控件的toolbox,使用過vs的就不用再多作說明了!

15

我們做一個簡單到不行的計算器,透過輸入兩個input,然後決定運算元,即時計算出結果

所以我們一如往常的把控件拉到視窗畫面中!像這樣!

16

方便的是他的設計器也可以幫你快速的建立應用程式的基本功能控件,而畫面的美觀與排列可以透過他的layout設定

快速達到有組織的程式介面!範例如下:(官網範例)

如何定義應用程式的Layout?

1.用UI Designer

clip_image001[5]

2.用程式定義

clip_image002

QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(nameLabel, 0, 0);
mainLayout->addWidget(nameLine, 0, 1);
mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
mainLayout->addWidget(addressText, 1, 1);

另外你可以透過物件指示器來看到你所拉的結構

17

你可以清楚看到他們的父子關係,而這些控件其實都是從他的函式庫由各widget類別所定義的

定義好畫面以後,我們先記錄一下我們有哪一些widget(控件)

運算子1:只能為整數          input1SpinBox:doubleSpinBox,讀取單行box中的double數字

運算元,定義加減乘除        OperatorComboBox:ComboBox,選項有+ – * /,分別對應index 1~4

運算子2:只能為整數          input2SpinBox:同1

運算結果(可以是doulbe)       lbl_Result:Label,同vs的label控件

建好了這些widget,我們必須要給他們加入事件來反應!一般在vs中,我們可以在控件的屬性視窗那邊去定義一些觸發的事件

在程式碼中也可以宣告與呼叫function或sub等程式。

 

在Qt這邊是透過Signals與Slots來定義物件的互動

clip_image001

因此如何讓Qt程式的Widget(按鈕)有他們的功能?

假如新增了一個按鈕,當我們觸發了按鈕的事件以後

例如:Clicked()(代表我們在按鈕上click了一下)

按鍵程式就會傳出一個Signals訊息

訊息必須要有Slots接口來接,因此您必須定義Slots的方法來取得signal的資料!而他們之間的connect建立方式有兩種

一種是手動的建立connect,在qt中可以透過表單設計器來透過控件精靈來透過內建的signal事件來找到slot接口

不過我們先瞭解qt的原理後,手動建一次看看

應用到我們的程式事件,我們想一想

當我們輸入數字以後、選擇不同的運算元以後,就要馬上執行計算!

因此我們必須透過widget的事件方法來偵測這些widget的變動!

除此之外,我們希望建立一個function,只要當widget一變動,程式就會自動呼叫計算的function,所以我們要先建立一個function看看

那如何新增一個自訂的function?C++中你都要先在類別標頭檔(.h)建立宣告

看你要開放還是私有,就放在對應的宣告區塊[return value type] + [function name] +([parameters type , name])

這邊建立的計算的function我們稱為:Exec

因此打開標頭檔calculator.h,建立一個function的宣告

   1: private:
   2:     Ui::CalculatorClass ui;
   3:     double Exec(int value1,int Op,int value2);

接著你可以在calculator.cpp檔中建立方法的實作:

   1: double CalculatorForm::Exec(double value1,int Op,double value2){
   2:     double result;
   3:     switch (Op)
   4:     {
   5:     case 1:
   6:         result = value1 + value2;
   7:         break;
   8:     case 2:
   9:         result = value1 - value2;
  10:         break;
  11:     case 3:
  12:         result = value1 * value2;
  13:         break;
  14:     case 4:
  15:         result = value1 / value2;
  16:         break;
  17:     }
  18:  
  19:     return result;
  20: }

註:記住要用double Calculator::來選取function Exec喲!

定義好方法後,我們就知道,當控件的變動事件一觸發,就把現在widget的值傳到這個function來

那控件的事件怎麼定義呢?

 

先前說明了Signals與Slots來定義物件的互動

因此我們先來定義一下有哪些slots方法(只要是方法也都是要在標頭檔.h中宣告哦)

此例中,signals的方法都是由widget的事件所定義,所以直接在Widget按右鍵有一個go to slots,就可以自動建立觸發事件與slot事件的關係(自動建立)

image

選擇一個字串變動的事件slots

image

我們就可以看到QT會自動幫我們建立觸發事件的方法與參數

.h檔會自動宣告,另外cpp檔會產生實作區

   1: void CalculatorForm::on_input1lineEdit_textChanged(QString input)
   2: {
   3:    //實作接收到signal後的行為
   4: }
   5:  
   6: void CalculatorForm::on_input2lineEdit_textChanged(QString input)
   7: {
   8:    //實作接收到signal後的行為
   9: }

至於如何自己手動建立connect呢?

本例的combobox則不透過自動建立事件的方式,所以要先到標頭檔(.h)中的slot方法區稱去宣告

這邊宣告的slots方法

   1: private slots:
   2:     void OperatorComboBoxChanged(int index);  //手動建立與手動命名
   3:     void on_input2lineEdit_textChanged(QString input); //自動建立與命名
   4:     void on_input1lineEdit_textChanged(QString input); //自動建立與命名

到同類別名cpp檔中的建構子(類似於Form_load事件),建立slots方法實作

   1: connect(ui->OperatorComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(OperatorComboBoxChanged(int)));

 

3.建立signals方法與剛剛建立的slots方法的連結

connect(傳送者,例如:ui->[控件名稱], SIGNAL([傳送者的觸發事件,例如click()]), 接收者物件名稱, SLOT([slot的方法名稱]()));

image

註:如何知道控件所有可以觸發的方法?

控件都會在ui的類別定義

所以可以透過ui物件來取得

1.透過ui->控件名稱->方法事件

2.直接在ui designer點選右鍵go to Slot(會讓你選擇內建名稱,列出有signals的方法)

 

最後我們完成我們的程式邏輯

1.在本視窗物件被建立的時候要將運算符號加減乘除setup起來,所以要在建構子來建立程式碼(類似form load事件)

   1: CalculatorForm::CalculatorForm(QWidget *parent) :
   2:     QWidget(parent),
   3:     ui(new Ui::CalculatorForm)
   4: {
   5:     //將ui物件設定成本物件
   6:     ui->setupUi(this);
   7:  
   8:  
   9:     //此為手動建立connect,其他input的事件自動建立關聯
  10:     connect(ui->OperatorComboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(OperatorComboBoxChanged(int)));
  11:  
  12:     //定義ComboBox控件的元件
  13:      ui->OperatorComboBox->addItem(tr("Choose")); //tr是指將字元轉換成QString
  14:      ui->OperatorComboBox->addItem(tr("+")); //1
  15:      ui->OperatorComboBox->addItem(tr("-")); //2
  16:      ui->OperatorComboBox->addItem(tr("*")); //3
  17:      ui->OperatorComboBox->addItem(tr("/")); //4
  18: }

2.當物件變動時,就要重新計算(這邊直接貼上,先不論程式碼的好壞),所有的控件觸發方法都要有這段邏輯哦!

包含了:

   1: private slots:
   2:     void OperatorComboBoxChanged(int index);  //手動建立與手動命名
   3:     void on_input2lineEdit_textChanged(QString input); //自動建立與命名
   4:     void on_input1lineEdit_textChanged(QString input); //自動建立與命名

 

之後有空再refactor他

   1: if (ui->OperatorComboBox->currentIndex()==3 && ui->input2SpinBox->value()==0){
   2:     QMessageBox::information(this, tr("錯誤"),tr("除數請勿為0"));
   3: }else{
   4:     ui->lbl_Result->setText(QString::number(
   5:             Exec(
   6:                     ui->input1SpinBox->value(),
   7:                     ui->OperatorComboBox->currentIndex(),
   8:                     ui->input2SpinBox->value())));
   9: }

咦有一個檔我們完全沒有動過,那就是main檔!

   1: int main(int argc, char *argv[])
   2: {
   3:     QApplication a(argc, argv);
   4:     CalculatorForm w;
   5:     w.show();
   6:     return a.exec();
   7: }

main檔之前說,是程式的進入點,所以在這邊我們也是沒有要改變!這邊的程式會建立一個Qapplication的實例

接著來Build看看吧

image

恩有了,視窗程式ok了!那這個專案先放一邊!

用VS 2008的命令提示字元輸入以下

1. cd C:\Users\PINNB\Documents\CalculatorForm(看自己設在哪)

2. nmake clean

3. qmake -config release

4. nmake

建置VC++專案

http://www.dotblogs.com.tw/pin0513/archive/2010/01/08/12918.aspx的方式加到專案中!

image 要執行qmake這個轉換指令

後續測試中囉