常用的窗體基類是 、 和 ,在創建 GUI 應用程序時選擇窗體基類就是從這 3 個類中選擇。
直接繼承于 ,是 和 的父類,其他繼承于 的窗體類還有 、 和 。另外還有一個類 ,它同時從 和 繼承。這些類的繼承關系如圖 1 所示。
圖 1 幾個窗體類的繼承關系
這些窗體類的主要特點和用途如下:
窗體類重要特性的設置
窗體顯示或運行的一些特性可以通過 的一些函數設置,如在前面章節種,介紹對話框的創建和使用時,有如下的代碼:
dlgLocate = new QWDialogLocate(this);
dlgLocate->setAttribute(Qt::WA_DeleteOnClose);
Qt::WindowFlags flags=dlgLocate->windowFlags();
dlgLocate->setWindowFlags(flags | Qt::WindowStaysOnTopHint);
這段代碼就用到了兩個設置函數——() 和 (),它們可以設置窗體的顯示特性和運行特性。
下面介紹 類中用于窗體屬性設置的幾個主要函數的功能。
()函數
() 函數用于設置窗體的一些屬性,其函數原型為:
void QWidget::setAttribute(Qt::WidgetAttribute attribute, bool on = true)
枚舉類型 Qt:: 定義了窗體的一些屬性,可以打開或關閉這些屬性。枚舉類型 Qt:: 常用的常量及其意義見表 2。
表 2 枚舉類型 常用的常量常量意義
Qt::
允許窗體接收拖放來的組件
Qt::
窗體關閉時刪除自己,釋放內存
Qt::
鼠標進入或移出窗體時產生paint事件
Qt::
窗體是否接受觸屏事件
()函數
() 函數用于設置窗體標記,其函數原型是:
void QWidget::setWindowFlags(Qt::WindowFlags type)
參數 type 是枚舉類型 Qt:: 的值的組合,用于同時設置多個標記。
另外一個函數 () 用于一次設置一個標記,其函數原型為:
void QWidget::setWindowFlag(Qt::WindowType flag, bool on = true)
可單獨打開或關閉某個屬性。枚舉類型 Qt:: 常用的常量值見表 3。
表 3 枚舉類型 Qt:: 常用的常量常量意義
表示窗體類型的常量
Qt::
這是 類的缺省類型。這種類型的窗體,如果它有父窗體,就作為父窗 體的子窗體;否則就作為一個獨立的窗口
Qt::
表明這個窗體是一個窗口,通常具有窗口的邊框、標題欄,而不管它是否有父窗體
Qt::
表明這個窗體是一個窗口,并且要顯示為對話框(例如在標題欄沒有最小化、 最大化按鈕)。這是 類的缺省類型
Qt::Popup
表明這個窗體是用作彈出式菜單的窗體
Qt::Tool
表明這個窗體是工具窗體,具有更小的標題欄和關閉按鈕,通常作為工具欄的 窗體
Qt::
表明這是用于 消息提示的窗體
Qt::
表明窗體是屏幕,是 類的缺省類型
Qt::
表明窗體是桌面,這是 類的類型
Qt::
表明窗體是子窗體,例如 就是這種類型
控制窗體顯示效果的常量
Qt::
在 平臺上,使窗口具有更窄的邊框,用于固定大小的對話框
Qt::
創建無邊框窗口
要定義窗體外觀定制窗體外觀的常量,需要先設置 Qt::
Qt::
關閉缺省的窗口標題欄
Qt::
窗口有標題欄
Qt::
有窗口系統菜單
Qt::Hint
有最小化按鈕
Qt::Hint
有最大化按鈕
Qt::int
有最小化、最大化按鈕
Qt::t
有關閉按鈕
Qt::Windo nt
有上下文幫助按鈕
Qt::
窗口總是處于最上層
Qt::int
窗口總是處于最下層
Qt::lnput
窗口只作為輸出,不接受輸入
Qt::、Qt:: 等表示窗體類型的常量可以使窗體具有缺省的外觀設置,如果設置為 Qt:: 類型,則窗體具有對話框的缺省外觀,例如標題欄沒有最小化、最大化按鈕。
控制窗體顯示效果和外觀的設置項可定制窗體的外觀,例如設置一個窗體只有最小化最大化按鈕,沒有關閉按鈕。
()函數
() 函數使窗口處于最小化、最大化等狀態,其函數原型是:
void QWidget::setWindowState(Qt::WindowStates windowstate)
枚舉類型 Qt:: 表示了窗體的狀態,其取值見表 4。
表 4 枚舉類型 Qt:: 的常量常量意義
Qt: :
正常狀態
Qt: :
窗口最小化
Qt::
窗口最大化
Qt::
窗口填充整個屏幕,而且沒有邊框
Qt::
變為活動的窗口,例如可以接收鍵盤輸入
()函數
() 函數用于設置窗口的模態,只對窗口類型有用。其函數原型為:
void setWindowModality(Qt::WindowModality windowModality)
枚舉類型 Qt:: 的取值意義見表 5。
表 5 枚舉類型Qt::的常量常量意義
Qt::
無模態,不會阻止其他窗口的輸入
Qt::
窗口對于其父窗口、所有的上級父窗口都是模態的
Qt::
窗口對整個應用程序是模態的,阻止所有窗口的輸入
()函數
() 函數用于設置窗口的透明度,其函數原型如下:
void ::(qreal level)
參數 level 是 1.0(完全不透明)至 0.0(完全透明)之間的數。窗口透明度缺省值是 1.0,即完全不透明。
多窗口應用程序的設計主窗口設計
本節以實例 演示多窗口應用程序的設計,實例主窗口如圖 6 所示。
圖 6 實例的主窗口
程序的主窗口類是 ,從 繼承。主窗口有一個工具欄,4 個創建窗體的按鈕以不同方式創建和使用窗體。主窗體工作區繪制一個背景圖片,有一個 組件,作為創建窗體的父窗體。沒有子窗體時, 不顯示。
下面是 的構造函數和繪制背景圖片的代碼:
QWMainWindow::QWMainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::QWMainWindow)
{
ui->setupUi(this);
ui->tabWidget->setVisible(false);
ui->tabWidget->clear();//清除所有頁面
ui->tabWidget->tabsClosable(); //Page有關閉按鈕,可被關閉
this->setCentralWidget(ui->tabWidget);
this->setWindowState(Qt::WindowMaximized); //窗口最大化顯示
this->setAutoFillBackground(true);
}
void QWMainWindow::paintEvent(QPaintEvent *event)
{ //繪制窗口背景圖片
Q_UNUSED(event);
QPainter painter(this);
painter.drawPixmap(0,ui->mainToolBar->height(),this->width(),this->height()-ui->mainToolBar->height()-ui->statusBar->height(),QPixmap(":/images/images/back2.jpg"));
}
在構造函數中,將 組件設置為不可見,并且頁面可關閉,這樣每個頁面標題部分都會出現一個關閉按鈕,單擊可以關閉頁面。
背景圖片繪制使用窗體的 () 事件,獲取主窗口的畫筆之后,將資源文件里的一個圖片繪制在主窗口的工作區。繪圖的內容在后續章節中詳細介紹。
實例除了主窗口之外,還有兩個窗口和兩個對話框:
類的設計
在 Qt 單擊File->New File or 菜單項,在出現的對話框里選擇創建Qt Form Class,并且在向導中選擇基類為 ,將創建的新類命名為 。
在 的窗口上只放置一個 組件。由于 是從 繼承而來的,在 UI 設計器里不能直接為 設計工具欄,但是可以創建 ,然后在窗體創建時用代碼創建工具欄。
圖 7 窗口設計的
圖 7 是設計的 除了 和 之外,其他編輯操作的 都和 相關槽函數關聯, 與窗口的 close() 槽函數關聯。
用于打開文件,用于設置文檔字體模態對話框是什么時候實例的對話框,這些功能在前面的例子里都遇到過,不是本實例的重點,不再介紹其實現代碼。
在 的構造函數里用代碼創建工具欄和布局,也可以在析構函數里增加一個消息顯示的對話框,以便觀察窗體是何時被刪除的。代碼如下:
QFormDoc::QFormDoc(QWidget *parent) :
QWidget(parent),
ui(new Ui::QFormDoc)
{
ui->setupUi(this);
//使用UI設計的Actions設計工具欄
QToolBar* locToolBar = new QToolBar(tr("文檔"),this); //創建工具欄
locToolBar->addAction(ui->actOpen);
locToolBar->addAction(ui->actFont);
locToolBar->addSeparator();
locToolBar->addAction(ui->actCut);
locToolBar->addAction(ui->actCopy);
locToolBar->addAction(ui->actPaste);
locToolBar->addAction(ui->actUndo);
locToolBar->addAction(ui->actRedo);
locToolBar->addSeparator();
locToolBar->addAction(ui->actClose);
locToolBar->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
QVBoxLayout *Layout = new QVBoxLayout();
Layout->addWidget(locToolBar); //設置工具欄和編輯器上下布局
Layout->addWidget(ui->plainTextEdit);
Layout->setContentsMargins(2,2,2,2); //減小邊框的寬度
Layout->setSpacing(2);
this->setLayout(Layout); //設置布局
}
QFormDoc::~QFormDoc()
{
QMessageBox::information(this, "消息", "QFormDoc對象被刪除和釋放");
delete ui;
}
類的使用
主窗口工具欄上的“嵌入式 ”按鈕的響應代碼如下:
void QWMainWindow::on_actWidgetInsite_triggered()
{
//創建QFormDoc窗體,并在tabWidget中顯示
QFormDoc *formDoc = new QFormDoc(this);
formDoc->setAttribute (Qt: : WA_DeleteOnClose) ; //關閉時自動刪除
int cur=ui->tabWidget->addTab(formDoc,QString::asprintf("Doc %d",ui->tabWidget->count()));
ui->tabWidget->setCurrentIndex(cur);
ui->tabWidget->setVisible(true);
}
這段代碼動態創建一個 類對象 ,并設置其為關閉時刪除。然后使用 的 () 函數,為主窗口上的 新建一個頁面,作為 的父窗體組件, 就在新建的頁面里顯示,我們稱這種窗體顯示方式為“嵌入式”。
主窗口工具欄上的“獨立 窗口”按鈕響應代碼如下:
void QWMainWindow::on_actWidget_triggered()
{
QFormDoc *formDoc = new QFormDoc(); //不指定父窗口,用show()顯示
formDoc->setAttribute(Qt::WA_DeleteOnClose); //關閉時自動刪除
formDoc->setWindowTitle("基于QWidget的窗體,無父窗口,關閉時刪除");
formDoc->setWindowFlag(Qt::Window,true);
//formDoc->setWindowFlag(Qt::CustomizeWindowHint,true);
//formDoc->setWindowFlag(Qt::WindowMinMaxButtonsHint,true);
//formDoc->setWindowFlag(Qt::WindowCloseButtonHint,true);
//formDoc->setWindowFlag(Qt::WindowStaysOnTopHint,true);
//formDoc->setWindowState(Qt::WindowMaximized);
formDoc->setWindowOpacity(0.9);
//formDoc->setWindowModality(Qt::WindowModal);
formDoc->show(); //在單獨的窗口中顯示
}
這里在創建 對象時,并沒有指定父窗口,創建窗口的代碼是:
QFormDoc *formDoc = new QFormDoc();
使用 () 函數,設置其為 Qt:: 類型,并用 show() 函數顯不窗口。這樣創建的是一個單獨顯示的窗口,并且在 的任務欄上會有顯示。若有文檔窗口打開,則關閉主窗口,而文檔窗口依然存在,實際上這時候主窗口是隱藏了。若關閉所有文檔窗口,主窗口自動刪除并釋放,才完全關閉應用程序。
如果創建 時指定主窗口為父窗口,即:
QFormDoc *formDoc = new QFormDoc(this);
則 不會在 的任務欄上顯示,關閉主窗口時,所有文檔窗口自動刪除。
圖 8 是嵌入式和獨立的 窗體的顯示效果,在創建獨立的顯示窗口時,還可以嘗試使用 () 函數設置不同的屬性,觀察這些屬性的控制效果。
圖 8 嵌入式和獨立的 窗體顯示效果
類的設計
表格窗口類 是基于 的可視窗口類,其功能與實例 主窗口類似,使用 模型和 組件構成 Model/View 結構的表格數據編輯器,并且可以調用 和 對話框進行表格大小設置和表頭設置。
該窗口的具體設計不詳細介紹了,只是為了觀察窗口刪除的時機,在析構函數里增加一個信息顯示對話框:
QFormTable::?QFormTable()
{
QMessageBox::information (this, "消息","FormTable 窗口被刪除和釋放"); delete ui;
}
類的使用
主窗口工具欄上的“嵌入式 ”按鈕的響應代碼如下:
void QWMainWindow::on_actWindowInsite_triggered()
{
QFormTable *formTable = new QFormTable(this);
formTable->setAttribute(Qt::WA_DeleteOnClose); //關閉時自動刪除
int cur=ui->tabWidget->addTab(formTable,QString::asprintf("Table %d",ui->tabWidget->count()));
ui->tabWidget->setCurrentIndex(cur);
ui->tabWidget->setVisible(true);
}
代碼功能是創建一個 對象 ,并在主窗口的 組件里新增一個頁面,將 顯示在新增頁面里。所以,即使是從 繼承的窗口類,也是可以在其他界面組件里嵌入式顯示的。
主窗口工具欄上的“獨立 窗口”按鈕響應代碼如下:
void QWMainWindow::on_actWindow_triggered()
{
QFormTable* formTable = new QFormTable(this);
formTable->setAttribute(Qt::WA_Delete〇nClose);
formTable->setWindowTitle ("基于 QMainWindow 的窗口,指定父窗口,關閉時刪除");
formTable->show();
}
這樣創建的 以獨立窗口顯示,關閉時自動刪除。它指定了主窗口為父窗口,主窗口關閉時,所有 類窗口自動刪除。
無論是嵌入式的,還是獨立的 窗口,都可以調用 和 對話框進行表格大小和表頭文字設置,對話框的調用方法在前面章節己有介紹。創建 嵌入式窗體和獨立窗口的運行效果如圖 9 所示。
圖 9 嵌入式和獨立的窗體顯示效果
類的控制
現在,單擊 中嵌入的 或 窗體工具欄上的“關閉”按鈕,都可以關閉窗體并且刪除分頁。但是單擊分頁上的關閉圖標,并不能關閉窗口。而且,關閉所有分頁后, 并沒有隱藏,無法顯示背景圖片。
為此,需要對 的兩個信號編寫槽函數,() 和 () 信號的槽函數代碼如下:
void QWMainWindow::on_tabWidget_tabCloseRequested(int index)
{//關閉Tab
if (index<0)
return;
QWidget* aForm=ui->tabWidget->widget(index);
aForm->close();
}
void QWMainWindow::on_tabWidget_currentChanged(int index)
{
bool en=ui->tabWidget->count()>0; //再無頁面時,actions禁用
ui->tabWidget->setVisible(en);
}
() 信號在單擊分頁的關閉圖標時發射,傳遞來的參數 index 表示頁面的編號。::() 返回 組件中某個頁面的窗體組件。獲取頁面的 組件后模態對話框是什么時候實例的對話框,調用 close() 函數關閉窗體。
刪除一個分頁或切換頁面時,會發射 () 信號,在此信號的槽函數里判斷分頁個數是否為零,以控制 是否可見。