目錄
按鈕類控件
Push Button
設置按鈕圖標
按鈕設置快捷鍵
設置鼠標點擊按鈕重復觸發
Radio Button
?單選框分組
Check Box?
顯示類控件
Label
常用屬性
設置文本格式
給Label設置圖片?
Label標簽設置邊框
設置文本對齊方式
設置文本自動換行
設置文本縮進
設置邊距
label設置伙伴?
LCD Number
核心屬性
示例:倒計時
ProgressBar
核心屬性?
示例:進度條
改變進度條的顏色?
Calendar Widget?
核心屬性
重要信號?
按鈕類控件
Push Button
使用QPushButton表示一個按鈕,QPushButton繼承自QAbstractButton,這個類是一個抽象類,是其他按鈕的父類。
QAbstractButton 中, 和 QPushButton 相關性較?的屬性 ?
屬性 | 說明 |
---|---|
text | 按鈕中的文本 |
icon | 按鈕中的圖標 |
iconSize | 按鈕中圖標的尺寸 |
shortCut | 按鈕對應的快捷鍵 |
autoRepeat | 按鈕是否會重復觸發. 當?標左鍵按住不放時, 如果設為 true, 則會持續產??標點擊事件; 如果設為 false, 則必須釋放?標, 再次按下?標時才能產?點擊事件. (相當于游戲?柄上的 "連發" 效果) |
autoRepeatDelay | 重復觸發的延時時間. 按住按鈕多久之后, 開始重復觸發 |
autoRepeatInterval | 重復觸發的周期. |
設置按鈕圖標
// 創建圖標
QIcon icon(":/doge.png");
// 設置圖標
ui->pushButton->setIcon(icon);
// 設置圖標??
ui->pushButton->setIconSize(QSize(50, 50));
按鈕設置快捷鍵
寫法一:
這種方法比較不容易出錯
ui->pushButton_up->setShortcut(QKeySequence(Qt::Key_W));
ui->pushButton_down->setShortcut(QKeySequence(Qt::Key_S));
ui->pushButton_left->setShortcut(QKeySequence(Qt::Key_A));
ui->pushButton_right->setShortcut(QKeySequence(Qt::Key_D));
寫法二:?
ui->pushButton_up->setShortcut(QKeySequence("w"));
ui->pushButton_down->setShortcut(QKeySequence("s"));
ui->pushButton_left->setShortcut(QKeySequence("a"));
ui->pushButton_right->setShortcut(QKeySequence("d"));
要設置組合快捷鍵的話,只需要要用 + 連接
ui->pushButton_up->setShortcut(QKeySequence(Qt::CTRL+Qt::Key_W));
?或者
ui->pushButton_right->setShortcut(QKeySequence("ctrl+d"));
設置鼠標點擊按鈕重復觸發
鍵盤事件的重發觸發默認開啟
ui->pushButton_up->setAutoRepeat(true);
Radio Button
屬性 | 說明 |
---|---|
checkable | 是否能選中 |
checked | 是否已經被選中,checkable是checked的前提條件 |
autoExclusive | 是否排他。 選中一個按鈕是否會取消其他按鈕的選中,對于QRadioButton來說默認是排他的 |
相關事件的功能:
- clicked 表??次 "點擊"
- pressed 表??標 "按下"
- released 表??標 "釋放"
- toggled 表?按鈕狀態切換.
?單選框分組
有時候一個界面需要多個單選按鈕組,組和組之間不能有排他,組內部排他,因此我們引入QButtonGroup類來進行分組
// 創建三個 QButtonGroupQButtonGroup* group1 = new QButtonGroup ( this );QButtonGroup* group2 = new QButtonGroup ( this );QButtonGroup* group3 = new QButtonGroup ( this );// 把 QRadioButton 兩兩?組 , 放到三個 QButtonGroup 中 .group1-> addButton (ui->radioButton);group1-> addButton (ui->radioButton_2);group2-> addButton (ui->radioButton_3);group2-> addButton (ui->radioButton_4);group3-> addButton (ui->radioButton_5);group3-> addButton (ui->radioButton_6);
Check Box?
ui->check_box->ischecked();
獲取多選框文本
ui->check_box->text();?
顯示類控件
Label
常用屬性
屬性 | 說明 |
---|---|
text? | QLabel中的文本 |
textFormat | ?本的格式. ? Qt::PlainText 純?本 ? Qt::RichText 富?本(?持 html 標簽) ? Qt::MarkdownText? ? markdown 格式 ? Qt::AutoText 根據?本內容?動決定?本格式 |
pixmap | QLabel 內部包含的圖?. |
scaledContent | 設為 true 表?內容?動拉伸填充 QLabel 設為 false 則不會?動拉伸 |
alignment | 對??式. 可以設置?平和垂直?向如何對?. |
wordWrap | 設為 true 內部的?本會?動換?. 設為 false 則內部?本不會?動換?. |
indent | 設置?本縮進. ?平和垂直?向都?效. |
margin | 內部?本和邊框之間的邊距. 不同于于 indent, 但是是上下左右四個?向都同時有效. ? indent 最多只是兩個?向有效(具體哪兩個?向有效取決于 alignment ) |
openExternalLinks | 是否允許打開?個外部的鏈接. (當 QLabel ?本內容包含 url 的時候涉及到) |
buddy | 給 QLabel 關聯?個 "伙伴" , 這樣點擊 QLabel 時就能激活對應的伙伴. 例如伙伴如果是?個 QCheckBox, 那么該 QCheckBox 就會被選中. |
設置文本格式
??? //第一個label設置成顯示純文本
??? ui->label_1->setTextFormat(Qt::PlainText);
??? ui->label_1->setText("這是?段純?本");
??? //第二個label設置成顯示富文本
??? ui->label_2->setTextFormat(Qt::RichText);
??? ui->label_2->setText("<b> 這是?段富?本 </b>");
??? //第三個label設置成顯示 markdown
??? ui->label_3->setTextFormat(Qt::MarkdownText);
??? ui->label_3->setText("## 這是?段 markdown ?本");
給Label設置圖片?
??? //先把QLabel 設置成和窗口一樣大,并且把這個QLabel左上角窗口的左上角
??? //讓整個QLabel鋪滿窗口
??? QRect windowRect = this->geometry();
??? ui->label->setGeometry(0,0,windowRect.width(),windowRect.height());
??? QPixmap pixmap(":/1.png");
??? ui->label->setPixmap(pixmap);
??? //QLalel跟窗口一樣大了,但是圖片不一定,因此需要拉伸圖片
??? ui->label->setScaledContents(true);
上述代碼我們是在窗口構造函數中寫的,因此我們如果再對窗口進行放大縮小,圖片并不能隨之變化,這里可以讓Wiget窗口類,重寫父類(QWidget)?resize 事件?(resizeEvent虛函數)
在鼠標拖動窗口尺寸的過程中,resizeEvent虛函數會被反復調用執行,每次觸發一個resizeEvent事件都會調用以此對應的虛函數,調用父類的虛函數就會實際調用子類的對應的函數(多態)
代碼示例:
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();
//這里void resizeEvent(QResizeEvent *event);private:Ui::Widget *ui;
};
#endif // WIDGET_H
?widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QLabel>
#include <QResizeEvent>//此處的形參event是非常有用的,這里就包含了觸發這個resize事件這一時刻,窗口的尺寸的數值
void Widget::resizeEvent(QResizeEvent *event)
{ui->label->setGeometry(0,0,event->size().width(),event->size().height());
}
Label標簽設置邊框
設置文本對齊方式
//垂直水平居中
?ui->label_1->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
Qt::AlignHCenter :水平方向上居中
Qt::AlignVCenter :垂直方向上居中
……
多個文本對齊方式之間使用 “ | ”?
設置文本自動換行
ui->label_1->setWordWrap(true);
設置文本縮進
??? ui->label_1->setWordWrap(true);
??? ui->label_1->setIndent(50);
有多行時,每行都會產生縮進?
設置邊距
ui->label_1->setMargin(10);
與indent不同的是,Margin是上下左右四個方向都一樣的邊距?
label設置伙伴?
示例界面如下:
?Qt中,QLabel中寫的文本,是可以指定“快捷鍵”,此處快捷鍵的規則功能上要比QPushButton弱很多,是在文本中使用 & 跟上一個字符來表示快捷鍵,比如 &A ,我們可以通過鍵盤上的 alt+a來觸發快捷鍵。
綁定了伙伴關系之后,通過快捷鍵就可以選中對應的單選按鈕/復選按鈕,這里的快捷鍵是在文本中寫 &A 類似的就可以了
LCD Number
QLCDNumber 是一個專門用來顯示數字的控件,類似于“老式計算機” 的效果。
核心屬性
屬性 | 說明 |
---|---|
intValue | QLCDNumber 顯?的數字值(int). |
value | QLCDNumber 顯?的數字值(double). 和 intValue 是聯動的. 例如給 value 設為 1.5, intValue 的值就是 2. 另外, 設置 value 和 intValue 的?法名字為 display , ?不是 setValue 或 者 setIntValue . |
digitCount | 顯??位數字. |
mode | 數字顯?形式.
只有?進制的時候才能顯??數點后的內容 |
segmentStyle | 設置顯??格.
|
smallDecimalPoint | 設置?較?的 ?數點 |
示例:倒計時
C++標準庫中,沒有提供定時器的實現,Boost里面提供了對應的功能
Qt中也封裝了對應的定時器(結合了信號槽的機制)
QTimer 通過這個類創建出來的對象,就會產生一個timeout這樣的信號,可以通過start方法來開啟定時器,并且參數中設定觸發timeout信號的周期,這樣結合connect,把這個timeout信號綁定到需要的槽函數中,就可以執行邏輯,修改LCD Number上面的數字了
代碼如下:
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void handle();
private:Ui::Widget *ui;QTimer* timer;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//初始值ui->lcdNumber->display("10");//創建一個QTimer實例timer=new QTimer(this);//把QTimer的timeout信號和咱們自己的槽函數進行連接connect(timer,&QTimer::timeout,this,&Widget::handle);//啟動定時器,參數是觸發timeout的周期,單位是mstimer->start(1000);
}Widget::~Widget()
{delete ui;
}void Widget::handle()
{//先拿到LCDNumber中的數字int value=ui->lcdNumber->intValue();if(value<=0){timer->stop();return;}ui->lcdNumber->display(value-1);
}
不使用QTimer的另一種寫法(實際不可行)
#include "widget.h"
#include "ui_widget.h"
#include <thread>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//初始值ui->lcdNumber->display("10");int value=ui->lcdNumber->intValue();while(true){std::this_thread::sleep_for(std::chrono::seconds(1));if(value<=0){break;}ui->lcdNumber->display(--value);}
}Widget::~Widget()
{delete ui;
}
對于GUI來說,內部包含了很多的隱藏狀態,Qt為了保證修改界面的過程中,線程安全是不會受到影響的,Qt禁止了其他線程直接修改界面,因此Qt為了確保線程安全,直接要求所有的對界面的修改操作,必須在主線程中完成,對于槽函數來說,默認情況下,槽函數都是由主線程調用的。
ProgressBar
使? QProgressBar 表示一個進度條
核心屬性?
屬性 | 說明 |
---|---|
minimum | 進度條最?值 |
maximum | 進度條最?值 |
value | 進度條當前值 |
alignment | ?本在進度條中的對??式
|
textVisible | 進度條的數字是否可?. |
orientation | 進度條的?向是?平還是垂直 |
invertAppearance | 是否是朝反?向增?進度 |
textDirection | ?本的朝向. |
format | 展?的數字格式.
|
示例:進度條
?代碼示例:
widget.h
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();void handle();
private:Ui::Widget *ui;QTimer* timer;};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);timer=new QTimer(this);connect(timer,&QTimer::timeout,this,&Widget::handle);timer->start(100);}Widget::~Widget()
{delete ui;
}void Widget::handle()
{int value=ui->progressBar->value();if(value>=100){timer->stop();return;}ui->progressBar->setValue(value+1);
}
在上述示例代碼中,widget.h中用到了QTimer,但是卻沒在.h文件中包含<QTimer>頭文件,為啥這個代碼編譯不會出錯?例如“找不到定義”之類的?
上述問題其實是通過Qt內部提供的一個特殊技巧來實現的,在Qt中,有一個專門的頭文件,這個頭文件包含了Qt中所有類的“前置聲明”,例如class QTimer;
Qt中問什么要使用上述的技巧,上述的技巧能解決什么問題?有啥提升呢?
主要解決的是編譯速度的問題,C/C++的代碼,編譯速度在其他語言橫向對比中,是非常慢的,因為C++編譯速度慢和 #include頭文件,有直接關系的,由于include關系錯綜復雜,因此,盡可能減少include頭文件的個數,就可以有效的減少編譯時間,Qt中就使用class前置聲明的方式,來盡量減少頭文件的包含
改變進度條的顏色?
Calendar Widget?
核心屬性
屬性 | 說明 |
---|---|
selectDate | 當前選中的日期 |
minimumDate | 最?日期 |
maximumDate | 最?日期 |
firstDayOfWeek | 每周的第?天(也就是?歷的第?列) 是周? |
gridVisible | 是否顯?表格的邊框 |
selectionMode | 是否允許選擇?期 |
navigationBarVisible | ?歷上?標題是否顯? |
horizontalHeaderFormat | ?歷上?標題顯?的?期格式 |
verticalHeaderFormat | ?歷第?列顯?的內容格式 |
dateEditEnabled | 是否允許?期被編輯 |
重要信號?
信號 | 說明 |
---|---|
selectionChanged(const QDate&) | 當選中的?期發?改變時發出 |
activated(const QDate&) | 當雙擊?個有效的?期或者按下回?鍵時發出,形參是?個QDate類型,保存 了選中的?期 |
currentPageChanged(int, int) | 當年份?份改變時發出,形參表?改變后的新年份和?份 |