界面編程之QT窗口系統20180726


/*******************************************************************************************/

一、坐標系統

坐標系統相對於對於父窗口而言(最外層的父窗口就是屏幕了,也可以說外面沒有窗口了,這時就是相對整個電腦屏幕而言了)

原點:就是左上角

x: 往右遞增

y: 往下遞增

具體見圖1:

 

具體示例:

    /* 對於主窗口,坐標系統相對於屏幕

     * 原點:相對於屏幕左上角

     * x: 往右遞增

     * y: 往下遞增

    */

    move(100, 100);

 

    /* 子窗口,坐標系統相對於父窗口

     * 原點:相對於窗口空白區域左上角(不包括邊框)

     * x: 往右遞增

     * y: 往下遞增

    */

    QPushButton *b1 = new QPushButton(this);

    b1->move(100, 100);

    b1->setText("^_^");

    b1->resize(200, 100);//設置大小

 

    QPushButton *b2 = new QPushButton(b1);

 

    b2->move(10, 10);

    b2->setText("@_@");

 

/*******************************************************************************************/

二、內存回收機制及qt對象模型

只要創建對象的時候指定了父對象,就會形成一個對象樹(我們創建的這個QObject對象會自動添加到其父對象的children()列表),

當程序結束的時候,qt就會自動的從對象樹葉子節點向根節點進行對象的釋放(當父對象析構的時候,這個列表中的所有對象也會被析構。注意,這里的父對象並不是繼承意義上的父類)。

驗證這個結論可以在對象的析構函數中加打印信息。

所以在qt中new了對象並指定了父對象就不需要delete了,注意QWidget的父對象是QObject。QObject是對象樹的根(當然,我們也可以自己刪除子對象,

它們會自動從其父對象的children()列表中刪除。比如,當我們刪除了一個工具欄時,其所在的主窗口會自動將該工具欄從其子對象列表中刪除,並且自動調整屏幕顯示)

 

// : QPushButton(parent) ,表示給基類QPushButton構造函數傳參

MyButton::MyButton(QWidget *parent) : QPushButton(parent)

{

}

 

MyButton *b3 = new MyButton(this);

b3->setText("123");

//自動釋放的前提條件:1)指定父對象后  2)直接或間接繼承於QObject

//子對象如果是動態分配空間的new,不需要手動釋放delete

//系統會自動釋放,自動回收

 

注意,所有窗口及窗口控件都是從QWidget直接或間接派生出來的。

 

注意,

如果QObject在棧上創建,Qt 保持同樣的行為。正常情況下,這也不會發生什么問題。來看下下面的代碼片段:

{

    QWidget window;

    QPushButton quit("Quit", &window);

}

作為父組件的 window 和作為子組件的 quit 都是QObject的子類(事實上,它們都是QWidget的子類,而QWidget是QObject的子類)。

這段代碼是正確的,quit 的析構函數不會被調用兩次,因為標准 C++要求,局部對象的析構順序應該按照其創建順序的相反過程。

因此,這段代碼在超出作用域時,會先調用 quit 的析構函數,將其從父對象 window 的子對象列表中刪除,然后才會再調用 window 的析構函數。

但是,如果我們使用下面的代碼:

{

    QPushButton quit("Quit");

    QWidget window;

    quit.setParent(&window);

}

情況又有所不同,析構順序就有了問題。我們看到,在上面的代碼中,作為父對象的 window 會首先被析構,因為它是最后一個創建的對象。

在析構過程中,它會調用子對象列表中每一個對象的析構函數,也就是說, quit 此時就被析構了。

然后,代碼繼續執行,在 window 析構之后,quit 也會被析構,因為 quit 也是一個局部變量,在超出作用域的時候當然也需要析構。

但是,這時候已經是第二次調用 quit 的析構函數了,C++ 不允許調用兩次析構函數,因此,程序崩潰了。

由此我們看到,Qt 的對象樹機制雖然幫助我們在一定程度上解決了內存問題,但是也引入了一些值得注意的事情。

這些細節在今后的開發過程中很可能時不時跳出來煩擾一下,所以,我們最好從開始就養成良好習慣,在 Qt 中,盡量在構造的時候就指定 parent 對象,並且大膽在堆上創建。

 

/*******************************************************************************************/

三、菜單欄_工具欄_狀態欄

1.QMainWindow

QMainWindow是一個為用戶提供主窗口程序的類,包含一個菜單欄(menu bar)、多個工具欄(tool bars)、多個錨接部件(dock widgets)、

一個狀態欄(status bar)及一個中心部件(central widget),是許多應用程序的基礎,如文本編輯器,圖片編輯器等,具體見圖2:

 

2.菜單欄

一個主窗口最多只有一個菜單欄。位於主窗口頂部、主窗口標題欄下面。

帶菜單欄的窗口在創建項目的時候選擇繼承的基類是QMainWindow(一般pc端用的最多)

#include <QMenuBar>//菜單欄

#include <QMenu>//菜單欄

#include <QAction>//菜單項

#include <QDebug>

#include <QToolBar>//工具欄

#include <QPushButton>

#include <QStatusBar>//狀態欄

#include <QLabel>

#include <QTextEdit>//文本編輯區

#include <QDockWidget>//浮動窗口

 

//菜單欄

QMenuBar *mBar = menuBar();//添加菜單欄,菜單欄里還沒有東西,mBar用於添加菜單

 

//添加菜單

QMenu *pFile = mBar->addMenu("文件");//pFile用於添加菜單項

//添加菜單項,也叫添加動作

QAction *pNew = pFile->addAction("新建");//動作pNew里面有信號。QAction::triggered表示點擊新建后發出的信號

connect(pNew, &QAction::triggered,

                   [=]()

                   {

                            qDebug() << "新建被按下";

                   }

                   );

pFile->addSeparator(); //添加分割線·

QAction *pOpen = pFile->addAction("打開");

 

2.工具欄

主窗口的工具欄上可以有多個工具條,通常采用一個菜單對應一個工具條的的方式,也可根據需要進行工具條的划分。

//工具欄,其實是菜單項的快捷方式

QToolBar *toolBar = addToolBar("toolBar");//添加工具欄,工具欄里還沒有東西

 

//工具欄添加快捷鍵(工具欄里添加內容)

toolBar->addAction(pNew);

QPushButton *b = new QPushButton(this);

b->setText("^_^");

//工具欄添加小控件(按鈕)

toolBar->addWidget(b);

connect(b, &QPushButton::clicked,

                   [=]()

                   {

                            b->setText("123");

                   }

                   );

                  

3.狀態欄

//狀態欄,一般是窗口的最下面,用來顯示狀態的

QStatusBar *sBar = statusBar();//添加狀態欄

QLabel *label = new QLabel(this);//標簽控件用於顯示內容

label->setText("Normal text file");

sBar->addWidget(label);//狀態欄使用標簽來顯示內容

//addWidget 從左往右添加狀態項,狀態欄中的狀態項不斷增加,各個狀態項之間有分割符,它們互相獨立,分別表示不同內容的狀態

sBar->addWidget(new QLabel("2", this));

// addPermanentWidget 從右往左添加

sBar->addPermanentWidget(new QLabel("3", this));

 

4.核心控件

//核心控件(文本編輯區)

QTextEdit *textEdit = new QTextEdit(this);//創建控件

setCentralWidget(textEdit);//添加核心控件(文本編輯區)

 

5.浮動窗口

//浮動窗口

QDockWidget *dock = new QDockWidget(this);//創建控件

addDockWidget(Qt::RightDockWidgetArea, dock);//添加浮動窗口,Qt::RightDockWidgetAre是枚舉類型,表示浮動窗口放的位置(右邊)

//給浮動窗口添加控件

QTextEdit *textEdit1 = new QTextEdit(this);

dock->setWidget(textEdit1);

 

6.具體見《QMainWindow》

 1 #ifndef MAINWINDOW_H
 2 #define MAINWINDOW_H
 3 
 4 #include <QMainWindow>
 5 
 6 class MainWindow : public QMainWindow
 7 {
 8     Q_OBJECT
 9 
10 public:
11     MainWindow(QWidget *parent = 0);
12     ~MainWindow();
13 };
14 
15 #endif // MAINWINDOW_H
mainwindow.h
 1 #include "mainwindow.h"
 2 #include <QMenuBar>
 3 #include <QMenu>
 4 #include <QAction>
 5 #include <QDebug>
 6 #include <QToolBar>
 7 #include <QPushButton>
 8 #include <QStatusBar>
 9 #include <QLabel>
10 #include <QTextEdit>
11 #include <QDockWidget>
12 
13 MainWindow::MainWindow(QWidget *parent)
14     : QMainWindow(parent)
15 {
16     //菜單欄
17     QMenuBar *mBar = menuBar();
18 
19     //添加菜單
20     QMenu *pFile = mBar->addMenu("文件");
21 
22     //添加菜單項,添加動作
23     QAction *pNew = pFile->addAction("新建");
24 
25     connect(pNew, &QAction::triggered,
26 
27             [=]()
28             {
29                 qDebug() << "新建被按下";
30             }
31 
32             );
33     pFile->addSeparator(); //添加分割線·
34     QAction *pOpen = pFile->addAction("打開");
35 
36     //工具欄,菜單項的快捷方式
37     QToolBar *toolBar = addToolBar("toolBar");
38 
39     //工具欄添加快捷鍵
40     toolBar->addAction(pNew);
41 
42     QPushButton *b = new QPushButton(this);
43     b->setText("^_^");
44     //添加小控件
45     toolBar->addWidget(b);
46 
47     connect(b, &QPushButton::clicked,
48             [=]()
49             {
50                 b->setText("123");
51             }
52             );
53 
54     //狀態欄
55     QStatusBar *sBar = statusBar();
56     QLabel *label = new QLabel(this);
57     label->setText("Normal text file");
58     sBar->addWidget(label);
59     //addWidget 從左往右添加
60     sBar->addWidget(new QLabel("2", this));
61 
62     // addPermanentWidget 從右往左添加
63     sBar->addPermanentWidget(new QLabel("3", this));
64 
65     //核心控件
66     QTextEdit *textEdit = new QTextEdit(this);
67     setCentralWidget(textEdit);
68 
69     //浮動窗口
70     QDockWidget *dock = new QDockWidget(this);
71     addDockWidget(Qt::RightDockWidgetArea, dock);
72 
73     //給浮動窗口添加控件
74     QTextEdit *textEdit1 = new QTextEdit(this);
75     dock->setWidget(textEdit1);
76 }
77 
78 MainWindow::~MainWindow()
79 {
80 
81 }
mainwindow.cpp

/*******************************************************************************************/

四、資源文件

1.介紹

Qt 資源系統是一個跨平台的資源機制,用於將程序運行時所需要的資源以二進制的形式存儲於可執行文件內部。

如果你的程序需要加載特定的資源(圖標、文本翻譯等),那么,將其放置在資源文件中,就再也不需要擔心這些文件的丟失。

也就是說,如果你將資源以資源文件形式存儲,它是會編譯到可執行文件內部。

2.使用

1).使用 Qt Creator 可以很方便地創建資源文件。我們可以在工程上點右鍵,選擇“添加新文件…”,可以在 Qt 分類下找到“Qt 資源文件”,見圖3:

 

2).點擊“選擇…”按鈕,打開“新建 Qt 資源文件”對話框。在這里我們輸入資源文件的名字和路徑,見圖4:

 

3).點擊下一步,選擇所需要的版本控制系統,然后直接選擇完成。我們可以在 Qt Creator 的左側文件列表中看到“資源文件”一項,

也就是我們新創建的資源文件,見圖5:

 

4).右側的編輯區有個“添加”,我們首先需要添加前綴,比如我們將前綴取名為 images。然后選中這個前綴,繼續點擊添加文件,

可以找到我們所需添加的文件。這里,我們選擇 document-open.png 文件。當我們完成操作之后,Qt Creator 應該是這樣子的,見圖6:

 

5).接下來,我們還可以添加另外的前綴或者另外的文件。這取決於你的需要。當我們添加完成之后,我們可以像前面一章講解的那樣,

通過使用 : 開頭的路徑來找到這個文件。比如,我們的前綴是 /images,文件是 document-open.png,

那么就可以使用:/images/document-open.png找到這個文件。這么做帶來的一個問題是,如果以后我們要更改文件名,比如將 docuemnt-open.png 改成 docopen.png,

那么,所有使用了這個名字的路徑都需要修改。所以,更好的辦法是,我們給這個文件去一個“別名”,以后就以這個別名來引用這個文件。

具體做法是,選中這個文件,添加別名信息,見圖7:

 

這樣,我們可以直接使用:/images/doc-open引用到這個資源,無需關心圖片的真實文件名。

如果我們使用文本編輯器打開 res.qrc 文件,就會看到一下內容:

<RCC>

             <qresource prefix="/images">

                 <file alias="doc-open">document-open.png</file>

             </qresource>

             <qresource prefix="/images/fr" lang="fr">

                 <file alias="doc-open">document-open-fr.png</file>

             </qresource>

</RCC>

我們可以對比一下,看看 Qt Creator 幫我們生成的是怎樣的 qrc 文件。當我們編譯工程之后,

我們可以在構建目錄中找到 qrc_res.cpp 文件,這就是 Qt 將我們的資源編譯成了 C++ 代碼。

 

/*******************************************************************************************/

五、模態和非模態對話框

對話框是 GUI 程序中不可或缺的組成部分。很多不能或者不適合放入主窗口的功能組件都必須放在對話框中設置。

對話框通常會是一個頂層窗口,出現在程序最上層,用於實現短期任務或者簡潔的用戶交互,對話框分為模態對話框和非模態對話框:

模態對話框只能操作當前的對話框,后面的東西(界面)沒法操作。同理非模態的就可以可以操作的

模態與非模態的實現:

         使用QDialog::exec()實現應用程序級別的模態對話框

         使用QDialog::open()實現窗口級別的模態對話框

         使用QDialog::show()實現非模態對話框。

 

#include <QDialog>//對話框

#include <QDebug>

#include <QMessageBox>

#include <QFileDialog>

 

QMenuBar *mBar = menuBar();

setMenuBar(mBar);

QMenu *menu = mBar->addMenu("對話框");

QAction *p1 = menu->addAction("模態對話框");

connect(p1, &QAction::triggered,

                   [=]()

                   {

                            QDialog dlg;

                            dlg.exec();//調出對話框,並且一直等在這里(阻塞),等事件(等用戶操作)

                            qDebug() << "111111";

                   }

                   );

QAction *p2 = menu->addAction("非模態對話框");

connect(p2, &QAction::triggered,

                   [=]()

                   {

//           dlg.show();//非阻塞,注意這個dlg不能使用局部變量,因為非阻塞所以局部變量會釋放掉就沒了

//           qDebug() << "111111";//使用動態分配或者成員變量都可以

 

 

//           QDialog *p = new QDialog(this);//這種方式也可以,但是程序結束才釋放,意味着一直點擊,內存就越來越少

//           p->show();

                             QDialog *p = new QDialog;//所以不指定父對象,那么釋放的方式是:通過設置屬性

                             p->setAttribute(Qt::WA_DeleteOnClose);//設置屬性為關閉的時候釋放(Qt::WA_DeleteOnClose 枚舉類型)

                             p->show();

                   }

                   );               

                                              

/*******************************************************************************************/

六、標准對話框

前面兩種創建的對話框僅僅就只是一個對話,沒有按鈕之類的。標准對話框:有按鈕的對話框

 

所謂標准對話框,是 Qt 內置的一系列對話框,用於簡化開發。事實上,有很多對話框都是通用的,

比如打開文件、設置顏色、打印設置等。這些對話框在所有程序中幾乎相同,因此沒有必要在每一個程序中都自己實現這么一個對話框。

Qt 的內置對話框大致分為以下幾類:

         QColorDialog:                          選擇顏色;

         QFileDialog:                     選擇文件或者目錄;

         QFontDialog:                            選擇字體;

         QInputDialog:                          允許用戶輸入一個值,並將其值返回;

         QMessageBox:                        模態對話框,用於顯示信息、詢問問題等;

         QPageSetupDialog:                為打印機提供紙張相關的選項;

         QPrintDialog:                           打印機配置;

         QPrintPreviewDialog:   打印預覽;

         QProgressDialog:          顯示操作過程。

 

1.消息對話框

 

#include <QMessageBox>//消息對話框

 

QAction *p3 = menu->addAction("關於對話框");

connect(p3, &QAction::triggered,

                   [=]()

                   {

                      QMessageBox::about(this, "about", "關於qt");//會產生一個有ok按鈕的對話框

                   }

                   );

QAction *p4 = menu->addAction("問題對話框");

connect(p4, &QAction::triggered,

                   [=]()

                   {

                   //QMessageBox::question(this,"question", "Are you ok?");//默認是yes,no兩個按鈕

                      int ret = QMessageBox::question(this,//返回值為用戶選中哪一個按鈕的值(枚舉)

                                                  "question", "Are you ok?",

                                                          QMessageBox::Ok |QMessageBox::Cancel

                                               );//MessageBox::Ok |QMessageBox::Cancel指定按鈕為ok和cancel兩個按鈕

                            switch(ret)

                            {

                                     case QMessageBox::Ok:

                                               qDebug() << "i am ok";

                                               break;

                                     case QMessageBox::Cancel:

                                               qDebug() << "i am bad";

                                               break;

                                     default:

                                               break;

                            }

                   }

                   );

                  

2.文件對話框

文件對話框:顯示一個讓用戶選擇文件的對話框

#include <QFileDialog>//文件對話框

 

QAction *p5 = menu->addAction("文件對話框");

connect(p5, &QAction::triggered,

                   [=]()

                   {

                      QString path = QFileDialog::getOpenFileName(

                                                  this,

                                                  "open",

                                                  "../",

                                                  "souce(*.cpp *.h);;Text(*.txt);;all(*.*)"//沒有這個參數則無法規定用戶選擇文件的格式,

                                                  );//"../"表示讓用戶選擇文件的路徑,也就是一打開顯示的界面

                      qDebug() << path;//獲取用戶選擇的文件,返回的是用戶選擇的文件的完整路徑

                   }

                   );                        

 

button->setGeometry();//設置按鈕的位置以及按鈕的大小

信號與槽具體見圖8,9

 

 

/*******************************************************************************************/

七、設計器的使用

從現在開始創建項目的時候,ui那個勾選框就要勾選上了。

勾選上項目中就會生成一個界面文件。

雙擊.ui界面文件就會自動的切換到設計器。

設計器作用:方便我們通過界面文件來設定窗口。

 

設計器里面也有信號與槽(這里添加的都只能用系統定義好的),不過一般不在這里操作,一般是在代碼里操作

 

ui->setupUi(this);//界面上的任何操作都是在這句話里完成的。ui代表ui界面的控件

ui->對象名;//這個對象名就是在設計器里面的控件

ui->myButton->setText("123");//修改設計器上已有的控件

 

/*******************************************************************************************/

八、常用控件

設計器左邊的控件分類介紹:

Layouts                               //布局

Spacers                               //空格,也是用來布局

Buttons(常用)                            //按鈕

Item Views                                 //數據和顯示是分離的,比如其中的listview就是類似表格,可以用來放置數據庫數據

Item Widgets                             //用來顯示項目和子項目的形式的,一層一層類似樹

Containers                                  //容器,容納一些別的控件,用於布局的時候很方便

Input Widgets(常用)     //輸入控件,比如輸入文本

Dispaly Widgets(常用)   //顯示控件,比如顯示圖片,顯示文字

 

1.Containers //容器中有:

         Tool Box //抽屜式容器,點擊一個選項就會展開來

         Tab Widget //標簽式容器,選擇點擊相應的標簽出現(切換到)相應的界面

         Stacked Widget //棧容器,內部也可以包含很多頁,但是里面沒有點擊,需要外部的按鈕之類的實現切換

 

         ui中可以直接對按鈕等信號添加槽函數,右擊按鈕選擇轉到槽即可,就會自動的在選擇的控件的類中添加槽函數了,這個槽函數

         在信號發出的時候會自動調用,無需connect,只需要在函數內部填上自己需要的邏輯就可以了。

         void MainWindow::on_change_clicked()

         {//自動添加的槽函數

                   static int i = 0;

                   ui->stackedWidget->setCurrentIndex( ++i % 4 );//點擊后不斷切換棧容器里面的頁面,

         }

        

         Frame //帶邊框的容器,常用於布局

         Widget //不帶邊框的容器,把窗口划分出若干部分方便布局,常用於布局

         MDI Araa //文檔分欄顯示

         Dock Widget //浮窗

         QAxWidget  //只能在win下使用,不常用

        

2.Input Widgets(常用)  //輸入控件中有:

         Conmbo Box //有選項,有下拉框

         Font Conmbo Box //字體選擇下拉框

         Line Edit //行編輯,只能寫一行,很常用,具體使用見講義,注意這個可以做出輸入有提示的效果

         //QLineEdit

    QString str = ui->lineEdit->text(); //獲取內容

    qDebug() << str;

    //設置內容

    ui->lineEdit->setText("12345678");

    //設置內容顯示間隙

    ui->lineEdit->setTextMargins(15, 0, 0, 0);//輸入內容的位置距離邊框上下左右的距離(unit:px)

         //設置內容顯示方式

    //ui->lineEdit->setEchoMode(QLineEdit::Password);//設置為密碼的顯示樣式 

         //設置輸入提示

         QStringList list;//字符串列表

    list << "hello" << "How are you" << "hehe";

    QCompleter *com = new QCompleter(list, this);//構建模型

    com->setCaseSensitivity(Qt::CaseInsensitive);//設置模型忽略大小寫

    ui->lineEdit->setCompleter(com);//設置輸入模型

        

         Text Edit //文本編輯區,可以多行,可以顯示圖片,或者網頁內容都是可以的

         Plain Text Edit //文本編輯區,可以多行,只能顯示文字

         Spin Box //微調整型數據,會有上下按鈕,點擊后數據會加或減

         Double Spin Box //微調Double型數據,會有上下按鈕,點擊后數據會加或減

         Time Edit  //和Spin Box類似,只是調時間的

         Date Edit  //和Spin Box類似,只是調日期的

         Date/Time Edit  //和Spin Box類似,只是調時間和日期的

         Dial //有個點在圈上轉的模型

         Horizontal Scroll Bar //單獨的一個水平滾動條

         Vertical Scroll Bar //單獨的一個垂直滾動條

         Horizontal Slider //水平滑塊,比如調音量,調播放時間軸那種

         Vertical Slider //垂直滑塊,比如調音量,調播放時間軸那種

         Key Sequence Edit //設置快捷方式使用

        

3.Dispaly Widgets(常用)  //顯示控件中有:

         Label//標簽,可以顯示文字,可以顯示圖片,可以顯示動畫,可以顯示網址

         //QLabel

    ui->labelText->setText("^_^"); //設置文本內容

    //設置圖片

    ui->labelImage->setPixmap(QPixmap("://image/LuffyQ.png"));//也可以在ui中的屬性欄中直接添加

    //讓圖片自動適應label大小

    ui->labelImage->setScaledContents(true);

    //創建動畫對象

    QMovie *myMovie = new QMovie("://image/mario.gif");

    //設置動畫

    ui->labelGif->setMovie(myMovie);

    //啟動動畫

    myMovie->start();

    ui->labelGif->setScaledContents(true);

         //設置html(超鏈接)

    ui->labelUrl->setText("<h1><a href=\"https://www.baidu.com\">百度一下</a></h1>");

    ui->labelUrl->setOpenExternalLinks(true);//設置點擊后可以跳轉,如果不設置就需要自己來處理信號自己增加槽函數哈哈哈

        

         Text Browser //文本瀏覽器,顯示文本,比如qq聊天界面,顯示雙方消息的界面

         Graphics View //繪圖的時候用到

         Calendar Widget //日歷控件

         LCD Number //數碼管,可以顯示整數,浮點型,字符串(只能a到f),也就是16進制

    //數碼管

    ui->lcdNumber->display(123); //設置內容

        

         Progress Bar //進度條

         //進度條

    ui->progressBar->setMinimum(0); //設置最小值

    ui->progressBar->setMaximum(200);//設置最大值

    ui->progressBar->setValue(100); //設置當前值

        

         Horizontal Line //水平線,分割線

         Vertical Line //垂直線,分割線

        

         QDeclarative View //QML用到

         QQuickWidget  //QML用到

         QWebView       //網頁顯示的地方,用來顯示網頁

         ui->webView_2->load(QUrl("http://www.baidu.com"));//需要加http,並且需要加上網頁控件模塊,也就是在項目文件中加上QT+=webkitWidgets

                  

沒有布局則縮放窗口,窗口內容不會跟着縮放。而布局后,縮放窗口,窗口中的內容也會跟着縮放。

 

3.Qt 提供了兩種組件定位機制:絕對定位和布局定位(借助qt里面的布局管理器)。

         絕對定位就是一種最原始的定位方法:給出這個組件的坐標和長寬值。

這樣,Qt 就知道該把組件放在哪里以及如何設置組件的大小。但是這樣做帶來的一個問題是,如果用戶改變了窗口大小,

比如點擊最大化按鈕或者使用鼠標拖動窗口邊緣,采用絕對定位的組件是不會有任何響應的。這也很自然,因為你並沒有告訴 Qt,

在窗口變化時,組件是否要更新自己以及如何更新。或者,還有更簡單的方法:禁止用戶改變窗口大小。但這總不是長遠之計。

         布局定位:你只要把組件放入某一種布局,布局由專門的布局管理器進行管理。當需要調整大小或者位置的時候,

         Qt 使用對應的布局管理器進行調整。

布局定位完美的解決了使用絕對定位的缺陷。

 

4.Qt 提供的布局中以下三種是我們最常用的:

     QHBoxLayout:按照水平方向從左到右布局;

     QVBoxLayout:按照豎直方向從上到下布局;

     QGridLayout:在一個網格中進行布局,類似於 HTML 的 table,類似表格,需要先擺好大致位置

1).布局都是在ui設計器里面做的。布局一般都是先局部后全局

 

2).布局的時候常用到spacers(彈簧)控件

spacer分為水平和垂直,其實他們都是不可見的控件,也就是空格,只是用來占位置的,通過

占位置實現我們想要的布局。

同時在spacer對應控件的屬性里,我們也可以修改其占用位置的大小。

 

3).兩個文本顯示區,可以來回拖動的那種效果,也是布局做的

 

4).存在(設置)布局后(包括水平,垂直,網格三種布局管理器),

則在屬性里面有layout一欄,表示當前控件的布局屬性,可以進行調整設置等。

注意這個調整還受限於屬性中的Qwidget欄中的水平或垂直策略。

 

5).布局的時候經常用到容器(比如容器中的Widget)將內容分為多個模塊,然后進行模塊與模塊之間的布局

對一個窗口進行布局,布局的是里面最外層的模塊。

 

/*******************************************************************************************/

九、自定義控件

#include <QSpinBox>//數字條

#include <QSlider>//滑塊

#include <QHBoxLayout>//水平布局

 

QSpinBox *spin = new QSpinBox(this);

QSlider *slider = new QSlider(Qt::Horizontal, this);//Horizontal指定滑塊的方向(水平)

//把控件添加到布局中

QHBoxLayout *hLayout = new QHBoxLayout(this);//指定父對象,表示該布局從屬於哪個控件中,也就是在哪個控件下

hLayout->addWidget(spin);

hLayout->addWidget(slider);

//setLayout(hLayout);//如果前面沒有指定父對象,則需要這里設置

//把當前通過布局形成的新的控件添加到ui里面的方法:

//在ui中添加一個新控件的基類的控件(Qwidget),然后右擊選擇提升為,在里面填上新控件的類名,見圖10,11

 

 

//然后全局包含打勾(方便再次添加該新的控件),點擊添加再點提升就可以了。見圖12

 

connect(spin, static_cast<void (QSpinBox::*)(int)>(&QSpinBox::valueChanged),//強制類型轉換(函數類型)

                   slider, &QSlider::setValue);

connect(slider,  &QSlider::valueChanged, spin, &QSpinBox::setValue);      

        

/*******************************************************************************************/

十、qt樣式表

Qt樣式表的思想很大程度上是來自於HTML的層疊樣式表css,通過調用Qwidget::setStyletSheet(QString)或者

Apllication::setStyleSheet(QString),就可以為一個獨立的子部件,整個窗口,甚至是整個應用指定一個樣式表。

 

Qt樣式表與CSS的語法規則幾乎完全相同。

Qt樣式表選擇器通常是一個類名,

具體見圖13,14

 

 

    this->setStyleSheet("QLabel{color:rgb(0, 255, 255);"//rgb表示通過紅綠藍配色

                        "background-color:red;"

                        "}");//表示整個控件(窗口)只要是QLabel的都是以這個為樣式

    ui->label->setStyleSheet("QLabel{color:rgb(0, 255, 255);"

                             "background-color:blue;"

                             "border-image:url(:/new/prefix1/image/Sunny.jpg);"//設置圖片背景

                            "}");

前景與背景:

具體見圖15

 

方箱模型(css 盒子):

具體見圖16

 

創建可縮放樣式:

    ui->label->setStyleSheet("QLabel{color:rgb(0, 255, 255);"

                             "background-color:blue;"

                             "border-image:url(:/new/prefix1/image/Sunny.jpg);"//border-image圖片自動適應控件大小,有圖片背景色就不生效

                             "border-image:url(:/new/prefix1/image/Sunny.jpg); 4 4 4 4 stretch stretch}");

                                                                  //4 4 4 4 stretch stretch表示四個方向裁剪4個像素后的進行縮放,比如控件向左縮放,則圖片隨之向左裁剪4個像素后的進行縮放。所以一般用的少

                                                                  

 

具體見圖17,18

 

 

處理偽狀態(css中也有對應的)

    ui->pushButton->setStyleSheet("QPushButton{"

                                  "border-image:url(:/new/prefix1/image/Sunny.jpg);"

                                  "}"

                                  "QPushButton:hover{"

                                  "border-image:url(:/new/prefix1/image/up.png);"

                                  "}"

 

                                  "QPushButton:pressed{"

                                  "border-image:url(:/new/prefix1/image/Luffy.png);"

                                  "}"

 

                                  );

 

具體見圖19,20

 

 

使用子部件點故意微觀樣式

具體見圖21

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM