一、基於Qt設計師
1.創建一個GUI項目,選擇“Qt4 Gui Application”。其中還有Empty Qt4 Project(空的工程),Qt4 Console Applicaiton(基於控制台的工程),Qt4 Gui Application(基於GUI設計的工程)。
2.填寫好項目名稱和目錄后,單擊下一步可以自己添加一些功能模塊。比如QtOpenGl,QtNetwork,Qtsql等等。
3.單擊下一步,選擇Base class(基類主要三種選擇:QWidget為窗口部件,QMaindow為主窗口,QDialog為對話框)。其它如Class name,Header file,Source file,Form file均可根據自己需要自行修改。選中Generate form復選框,表示要用自帶的界面設計器來設計界面,否則需要用代碼完成界面設計。最后單擊Finish按鈕,完成創建,則相應的文件自動加載到文件列表中去。
4.雙擊Dialog.ui,則進入Qt Designer。
5.進入程序代碼文件
先看Dialog.h頭文件
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
//用namespace定義一個全局名稱空間Ui(也可以稱為域,類似於C語言中的全局變量),用於解決在程序中存在同名標識存在的潛在危機。在名稱空間中可以封裝一些函數、類以及數據成員,用於細化管理。
//當在源文件中使用這個全局空間內成員時,有兩種方法:第一種為直接在成員名前面加上作用域如Ui::Dialog表示使用Ui域中的Dialog類;第二種則在程序開頭加上using namespace Ui,聲明使用作用域Ui,則可直接使用Dialog類。
namespace Ui {class Dialog;} //在ui_dialog.h文件中定義了命名空間Ui,其中還定義了一個繼承自Ui_Dialog類的Dialog類。這里只是對Ui域中Dialog類的前置聲明,以便加快編譯速度,同時避免在一個頭文件中隨意包含其他頭文件而產生錯誤,而這里只使用了該類對象的指針,不需要該類的完整定義,因此可以使用前置聲明。
class Dialog : public QDialog //定義一個QDialog的派生類(公有繼承)
{
Q_OBJECT //宏名,這個宏必須出現在類的私有聲明區,以啟動元對象QOject的特性(元對象編譯器moc)
public:
explicit Dialog(QWidget *parent = 0);
//parent指定Dialog的父窗口部件,parent=0表示窗口部件為一個窗口,否則為parent的子窗口控件
//構造函數,explicit只對構造函數起作用,用來抑制隱式轉換(默認為隱式轉換,explicit可以有效得防止構造函數的隱式轉換帶來的錯誤或者誤解)
//按照默認規定,只有一個參數的構造函數也定義了一個隱式轉換(如QString s = "hello"經過隱式轉換,等價於QString s=QString("hello")或者QString s("hello")),將該構造函數對應數據類型的數據轉換為該類對象。而explicit則不允許QString s="hello"這種初始化方式,使得編譯不能通過。
~Dialog(); //析構函數
private slots:
void on_countBtn_clicked();//單擊按鈕顯示圓面積
//void on_radiuslineEdit_textChanged(const QString &arg1);//在lineEdit控件中輸入圓的半徑,在areaLabel_2中直接顯示出圓的面積
private:
Ui::Dialog *ui; //定義一個私有成員的Ui::Dialog類指針成員,注意此時Ui:: Dialog與繼承於QDialog類的子類Dialog是不同的類,因為它們屬於不同的域(即不同的全局名稱空間),在cpp文件中會用ui->setupUi函數將UI文件中的界面應用於Dialog類的對象。
};
#endif //DIALOG_H
再看Dialog.cpp源文件
#include "dialog.h"
#include "ui_dialog.h"
const static double PI=3.1416; //定義一個全局變量
Dialog::Dialog(QWidget *parent) : //構造函數(帶有一個QWidget指針型參數)
QDialog(parent), //調用基類構造函數初始化基類QDialog,表示子類Dialog將父窗口參數傳遞給基類,說明也為QDialog的父窗口
ui(new Ui::Dialog) //在構造函數中用new為指針成員開辟獨立的動態內存空間,這里是為Dialog類中Ui::Dialog類對象成員ui開辟內存空間
{
ui->setupUi(this); //在頭文件中定義的Ui::Dialog類指針成員,在這里進行初使化ui,在產生界面后,setupUi()會根據naming convention對slot進行連接
}
Dialog::~Dialog() //析構函數
{
delete ui; //在析構函數中用delete釋放構造函數中用new開辟的動態內存空間,因為ui沒有父窗口,只有那些沒有parent的物件才使用delete來消除
}
//單擊按鈕顯示圓面積,這個是在界面設計時右鍵按鈕控件,然后單擊“go to slot(轉到槽)”產生的槽函數
void Dialog::on_countBtn_clicked()
{
bool ok;
QString tempStr;
QString valueStr=ui->radiuslineEdit->text();
int valueInt=valueStr.toInt(&ok);
double area=valueInt*valueInt*PI;
ui->areaLablel_2->setText(tempStr.setNum(area));
}
/////////////////////////////////////////////////////////////////
//在lineEdit控件中輸入圓的半徑,在areaLabel_2中直接顯示出圓的面積
void Dialog::on_radiuslineEdit_textChanged(const QString &arg1)
{
bool ok;
QString tempStr;
QString valueStr=ui->radiuslineEdit->text();
int valueInt=valueStr.toInt(&ok);
double area=valueInt*valueInt*PI;
ui->areaLablel_2->setText(tempStr.setNum(area));
}
////////////////////////////////////////////////////////////////
最后看main.cpp源文件
#include <QtGui/QApplication> //在每一個使用Qt圖形化應用程序中必須使用一個QApplication對象,它管理了圖形化應用程序的廣泛資源,基本設置,控制流及事件處理
#include "dialog.h" //完成dialog類的定義,注意使用哪個類時就必須將包含該類的頭文件引用過來
int main(int argc, char *argv[])
{
QApplication a(argc, argv); //a是QApplication類的實例對象,任何Qt的窗口系統部件被使用之前必須一 個創建QApplication對象
Dialog w; //創建一個對話框對象,即Dialog實例對象
w.show(); //在創建一個窗口部件的時候,默認是不可見的,必須用shou()函數使之變成可見
return a.exec(); //程序進入消息循環,等待可能輸入進行響應。這里就是main()把控制權轉交給Qt,Qt完成事件處理后,當應用程序退出時,exec()的值就會返回。
//在exec()中,Qt接受並處理用戶和系統的事件並且把它們傳遞給適當的窗口部件
}
7.運行程序
二、完全用編寫代碼的方式
1.創建項目與用Designer設計大體相同,只是要取消選中Generate form復選框。
2.進入程序代碼文件
先看Dialog.h頭文件
#ifndef DIALOG_H
#define DIALOG_H
#include <QtGui/QDialog> //添加用到的頭文件
#include <QLabel> //添加用到的頭文件
#include <QLineEdit> //添加用到的頭文件
#include <QPushButton> //添加用到的頭文件
class Dialog : public QDialog //類Dialog為基類QDialog的派生類(公有繼承)
{
Q_OBJECT //這個宏的作用是啟動Qt元對象系統的一些特性,如支持信號和槽,必須放置到類定義的私有區
public:
Dialog(QWidget *parent = 0); //構造函數,這里沒有用explicit來抑制構造函數的隱式轉換。parent指定Dialog的父窗口部件,parent=0表示窗口部件為一個窗口,否則為parent的子窗口部件
~Dialog();
private: //添加私有窗口部件變量
QLabel *label1,*label2; //添加QLabel類的指針型控件
QLineEdit *lineEdit; //添加QLineEdit類的指針型控件
QPushButton *button; //添加QPushButton類的指針型控件
private slots: //添加私有槽函數
void showArea();
};
#endif // DIALOG_H
再看Dialog.cpp源文件
#include "dialog.h"
#include <QGridLayout>//添加使用到的頭文件,也可以寫成#include "QGridLayout.h"
const static double PI=3.1416; //添加全局變量
Dialog::Dialog(QWidget *parent) //構造函數
: QDialog(parent)
{
label1=new QLabel(this); //這里的this指定父窗口
label1->setText(tr("請輸入圓的半徑:"));//QObject::tr()
lineEdit=new QLineEdit(this);
label2=new QLabel(this);
button=new QPushButton(this);
button->setText(tr("顯示對應圓的面積"));
QGridLayout *mainLayout=new QGridLayout(this);//網格布局
mainLayout->addWidget(label1,0,0);
mainLayout->addWidget(lineEdit,0,1);
mainLayout->addWidget(label2,1,0);
mainLayout->addWidget(button,1,1);
setLayout(mainLayout);
connect(button,SIGNAL(clicked()),this,SLOT(showArea()));//單擊按鈕顯示圓面積
//connect(lineEdit,SIGNAL(textChanged(QString)),this,SLOT(showArea()));//當行編輯控件中輸入半徑時,不必單擊按鈕,直接在label2中顯示出面積
}
Dialog::~Dialog() //析構函數
{
}
void Dialog::showArea() //添加的槽函數
{
bool ok;
QString tempStr;
QString valueStr=lineEdit->text();
int valueInt=valueStr.toInt(&ok);
double area=valueInt*valueInt*PI;
label2->setText(tempStr.setNum(area));
}
最后看main.cpp源文件
#include <QtGui/QApplication>
#include "dialog.h"
#include <QTextCodec> //人為添加使用的頭文件
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
//使用tr()函數將字符串翻譯成本地字符編碼類型,用於解決中文亂碼問題,使用UI界面設計時則不需要,在ui_xxx.h中自動將漢字轉化成utf8編碼格式
//QTextCodec::setCodecForLocale (QTextCodec::codecForLocale());
//使用QString::fromLocal8Bit()將字符串翻譯成本地字符編碼類型
//QTextCodec::setCodecForCStrings (QTextCodec::codecForLocale());
//使用QString ()將字符串翻譯成本地字符編碼類型
Dialog w;
w.show();
return a.exec();
}