導語
程序要實現的功能是:程序開始出現一個對話框,按下按鈕后便能進入主窗口,如果直接關閉這個對話框,便不能進入主窗口,整個程序也將退出。當進入主窗口后,我們按下按鈕,會彈出一個對話框,無論如何關閉這個對話框,都會回到主窗口。
程序里我們先建立一個工程,設計主界面,然后再建立一個對話框類,將其加入工程中,然后在程序中調用自己新建的對話框類來實現多窗口。
在這一篇還會涉及到代碼里中文字符串顯示的問題。
環境是:
Windows 7 + Qt 4.8.1 +Qt Creator 2.4.1
目錄
一、添加主窗口
二、代碼中的中文顯示
三、添加登錄對話框
四、使用自定義的對話框類
正文
一、添加主窗口
1.
我們打開Qt Creator
,新建Qt Gui
應用,項目名稱設置為“nWindows
”,在類信息界面保持基類為QMainWindow
,類名為MainWindow
,這樣將會生成一個主窗口界面。
2.
完成項目創建后,打開mainwindow.ui
文件進入設計模式,向界面上拖入一個Push Button
,然后對其雙擊並修改顯示文本為“按鈕”,如下圖所示。
3.
現在運行程序,發現中文可以正常顯示。在設計模式可以對界面進行更改,那么使用代碼也可以完成相同的功能,下面就添加代碼來更改按鈕的顯示文本。
二、代碼中的中文顯示
1.
我們點擊Qt Creator
左側的“編輯”按鈕進入編輯模式,然后雙擊mainwindow.cpp
文件對其進行編輯。在構造函數MainWindow()
中添加代碼:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->pushButton->setText("新窗口"); //將界面上按鈕的顯示文本更改為“新窗口”
}
這里的ui
對象就是界面文件對應的類的對象,在mainwindow.h
文件中對其進行了定義,我們可以通過它來訪問設計模式添加到界面上的部件。前面添加的按鈕部件Push Button
,在其屬性面板上可以看到它的objectName
屬性的默認值為pushButton
,這里就是通過這個屬性來獲取部件對象的。
我們使用了QPushButton
類的setText()
函數來設置按鈕的顯示文本,現在運行程序,效果如下圖所示。
2.
我們發現,在代碼中來設置按鈕的中文文本出現了亂碼。這個可以有兩種方法來解決,一個就是在編寫程序時使用英文,當程序完成后使用Qt
語言家來翻譯整個軟件中的顯示字符串;還有一種方法就是在代碼中設置字符串編碼,然后使用函數對要在界面上顯示的中文字符串進行編碼轉換。因為翻譯一個軟件很麻煩,對於這些小程序,我們希望中文可以立即顯示出來,所以下面來講解第二種方法。
3.
設置字符串編碼,可以使用QTextCodec
類的setCodecForTr()
函數,一般的使用方法就是在要進行編碼轉換之前調用該函數,下面我們在main.cpp
文件中添加代碼:
#include
<QtGui/QApplication>
#include
"mainwindow.h"
#include
<QTextCodec>
//
添加頭文件
int
main(int argc, char *argv[])
{
QApplication
a(argc,
argv);
QTextCodec
::
setCodecForTr(QTextCodec::codecForLocale());
//
設置編碼
MainWindow
w;
w.
show();
return
a.
exec();
}
因為我們要在MainWindow
類中進行編碼轉換,所以要在創建w
對象以前調用該函數。這里的codecForLocale()
函數返回適合本地環境的編碼,當然,也可以指定編碼,例如要設置為“GB2312”,可以使用下面的代碼:
QTextCodec
::setCodecForTr(QTextCodec::codecForName("GB2312"));
當設置完編碼后,就要在顯示中文字符串的地方使用tr()
函數,這里我們需要將修改按鈕顯示文本的代碼更改為:
ui
->
pushButton
->setText(tr("
新窗口
"
));
現在運行程序,可以發現中文已經可以正常顯示了。這里提示一下,如果感覺編輯器中的字體太小,可以使用Ctrl + +(同時按下Ctrl和加號鍵)來進行放大,使用Ctrl+ -可以縮小。
三、添加登錄對話框
1.
往項目中添加新文件,這里可以在編輯模式的項目目錄上點擊鼠標右鍵,然后選擇添加新文件菜單,如下圖所示。當然也可以在文件菜單中進行添加。
2.
模板選擇Qt
設計師界面類,然后界面模板選擇Dialog without Butt**
,如下圖所示。
3.
點擊下一步進入類信息界面,這里將類名更改為LoginDlg
(注意類名首字母一般大寫)。如下圖所示。
4.
當完成后會自動跳轉到設計模式,對新添加的對話框進行設計。我們向界面上拖入一個Push Button
,然后更改顯示文本為“登錄到主界面”。為了實現點擊這個按鈕后可以關閉該對話框並顯示主窗口,我們需要設置信號和槽的關聯。點擊設計模式上方的
圖標,或者按下F4
,便進入了信號和槽編輯模式。按着鼠標左鍵,從按鈕上拖向界面,如下圖所示。
當放開鼠標后,會彈出配置連接對話框,這里我們選擇pushButton
的clicked()
信號和LoginDlg
的accept()
槽並按下確定按鈕。如下圖所示。
設置好信號和槽的關聯后,界面如下圖所示。
這里簡單介紹一下信號和槽,大家可以把它們都看做是函數,比如這里,當單擊了按鈕以后就會發射單擊信號,即clicked();然后對話框接收到信號就會執行相應的操作,即執行accept()槽。一般情況下,我們只需要修改槽函數即可,不過,這里的accept()已經實現了默認的功能,它會將對話框關閉並返回Accepted,所以我們無需再做更改。下面我們就是要使用返回的Accepted來判斷是否按下了登錄按鈕。
完成后,可以按下
或者按下F3
來返回控件編輯模式。
四、使用自定義的對話框類
1.
按下Ctrl+2
返回代碼編輯模式,在這里打開main.cpp
文件,添加代碼:
#include
<QtGui/QApplication>
#include
"mainwindow.h"
#include
<QTextCodec>
//
添加頭文件
#include
"logindlg.h"
//
添加頭文件
int
main(int argc, char *argv[])
{
QApplication
a(argc,
argv);
//
QTextCodec::setCodecForTr(QTextCodec::codecForLocale());
//
設置編碼
QTextCodec
::
setCodecForTr(QTextCodec::codecForName("GB2312"));
MainWindow
w;
LoginDlg
dlg;
//
建立自己新建的類的對象dlg
if
(dlg.
exec() == QDialog::Accepted) //
利用Accepted返回值判斷按鈕是否被按下
{
w.
show(); //
如果被按下,顯示主窗口
return
a.
exec(); //
程序一直執行,直到主窗口關閉
}
else
return
0
;
//
如果沒被按下,則不會進入主窗口,整個程序結束運行
}
在這里,我們先創建了LoginDlg
類的對象dlg
,然后讓dlg
運行,即執行exec()
函數,並判斷對話框的返回值,如果是按下了登錄按鈕,那么返回值應該是Accepted
,這時就顯示主窗口,並正常執行程序;如果沒有按下登錄按鈕,那么就結束程序。
現在大家可以運行程序,測試一下效果。
2.
上面講述了一種顯示對話框的情況,下面再來講述一種情況。我們打開mainwindow.ui
文件進入設計模式,然后在按鈕部件上單擊鼠標右鍵並選擇轉到槽菜單,如下圖所示。
在彈出的轉到槽對話框中選擇clicked()
信號並按下確定按鈕。這時會跳轉到編輯模式mainwindow.cpp
文件的on_pushButton_clicked()
函數處,這個就是自動生成的槽,它已經在
mainwindow.h
文件中進行了聲明。我們只需要更改函數體即可。這里更改為:
void
MainWindow
::
on_pushButton_clicked()
{
QDialog
*dlg
=
new
QDialog
(
this
);
dlg->
show();
}
我們創建了一個對話框對象,然后讓其顯示,這里的this參數表明這個對話框的父窗口是MainWindow。注意這里還需要添加#include <QDialog>頭文件包含。有的童鞋可能會問,這里如果多次按下按鈕,那么每次都會生成一個對話框,是否會造成內存泄露或者內存耗盡。這里簡單說明一下,因為現在只是演示程序, Qt的對象樹機制保證了不會造成內存泄露,而且不用寫delete語句;而且因為是桌面程序,對於這樣一個簡單的對話框,其使用的內存可以被忽略。
當然,嚴謹的童鞋也可以在mainwindow.h文件中先定義一個對話框對象,並再在構造函數中進行創建,然后再到這里使用。
下面大家可以運行一下程序,查看效果。
結語
這個程序里我們實現了兩類窗口打開的方式,一個是自身消失而后打開另一個窗口,一個是打開另一個窗口而自身不消失。可以看到他們實現的方法是不同的