Qt6.0開發 第四章 常用界面組件的使用
第四章 常用界面組件的使用
在Qt類庫中,所有界面組件類的字節或間接父類都是QWidget.
QWidget的父類是QObject與QPaintDevice.所以QWidget是多重繼承的類.
QObject支持元對象系統,其信號與槽機制為編程中對象間通信提供了極大便利.
QPaintDevice是能使用QPainter類在繪圖設備上繪圖的類.
所有從QWidget繼承而來的界面組件被稱為widget組件,他們是構成GUI應用程序的窗口界面基本元素.
界面組件可以從窗口系統接收鼠標事件,鍵盤事件和其他事件,然后在屏幕上繪制自己.
常用的界面組件
按鈕類組件
按鈕類繼承關系:
- QAbstractButton:抽象類,提供按鈕共有特性
- QPushButton:普通按鈕
- QCommandLinkButton:單選按鈕,多個互斥項間選擇.
- QToolButton:工具按鈕
- QRadioButton:單選按鈕
- QCheckBox:復選框
- QPushButton:普通按鈕
- QDialogButttonBox:復合組件類,可設置為多個按鈕組合
輸入類組件
輸入類組件繼承關系:
- QComboBox:下拉列表框,也稱組合框
- QFontComboBox:字體下拉列表框,自動從系統獲取字體
- QLineEdit:編輯框,用于輸入單行文字
- QFrame:基本控件的基類
- QAbstractScrollArea:抽象類
- QTextEdit:文本編輯框,支持富文本格式,包括markdown.
- QPlainTextEdit:純文本編輯器,支持多段落純文本.
- QAbstractScrollArea:抽象類
- QAbstractSpinBox:抽象類
- QSpinBox:整數輸入框,用于輸入整數或離散型數據.
- QDoubleSpinBox:浮點數輸入框.
- QDateTimeEdit:允許用戶編輯日期與時間
- QDateEdit:日期編輯框
- QTimeEdit:時間編輯框
- QAbstractSlider:抽象類
- QDial:表盤,用于在設定的范圍內輸入和顯示數值.
- QScrollBar:卷滾條,用于在大的顯示區域內滑動.
- QSlider:滑動條,具有設定的數值范圍.
- QKeySequenceEdit:按鍵序列編輯器,一般用于處理快捷鍵
顯示類組件
顯示類組件繼承關系:
- QFrame:基本控件的基類
- QLabel:標簽,用于顯示文字,圖片等
- QAbstractScrollArea:抽象類
- QTextEdit:文本編輯框,支持富文本格式,包括markdown.
- QTextBrowser:文本瀏覽器,用于顯示富文本格式內容
- QGraphicsView:圖形視圖組件,圖形/視圖架構中的視圖組件
- QTextEdit:文本編輯框,支持富文本格式,包括markdown.
- QLCDNumber:LCD數字顯示組件,模仿LCD顯示效果的組件
- QCalendarWidget:日歷組件,用于顯示日歷
- QProgressBar:進度條,用于表示某個操作的進度
- QOpenGLWidget:OpenGL顯示組件,用于在Qt程序啟動OpenGL圖形
- QQuickWidget:QML顯示組件,用于自動加載QML文件
容器類組件
容器類組件繼承關系:
- QGroupBox:分組框,具有標題和邊框的容器組件
- QFrame:框架組件,是具有邊框的界面組件的父類
- QAbstractScrollArea:抽象類
- QScrollArea:卷滾區域,具有水平和垂直滾動條的容器
- QMdiArea:MDI工作區組件,在MDI應用程序中用于管理多文檔窗口
- QToolBox:工具箱,垂直方向的多頁容器組件
- QStackedWidget:堆疊多頁組件,沒有標簽欄的多頁組件
- QAbstractScrollArea:抽象類
- QTabWidget:帶標簽欄的多頁組件
- QDockWidget:停靠組件,可以??吭赒MainWindow窗口的??繀^域,也可以浮動
- QAxWidget:ActiveX顯示組件,用于顯示ActiveX控件
Item組件
Item組件繼承關系:
- QAbstractItemView
- QListView
- QUndoView
- QListWidget
- QTreeView
- QTreeWidget
- QTableView
- QTableWidget
- QColumnView
- QListView
Item Views組件大多是用于模型/視圖結果,每一種視圖組件需要相應的一種模型用于存儲數據.
Item Widgets組件類是相應Item Views組件類的子類,它們直接使用項(item)存儲數據,稱為相應視圖類的便利類(convenience class)
其他界面類
還有一些界面組件并沒有出現在組件面板里,例如常用的菜單欄(QMenuBar類),菜單(QMenu類),工具欄(QToolBar類),狀態欄(QStatusBar類)等組件.
QWidget類的主要屬性和接口函數
QWidget作為界面組件時的屬性
| 屬性名稱 | 屬性值類型 | 功能 |
|---|---|---|
| enabled | bool | 組件的使能狀態 |
| geometry | QRect | 組件的幾何形狀 |
| sizePolicy | QSizePolicy | 組件默認的布局特性 |
| minimumSize | QSize | 組件最小尺寸 |
| maximumSize | QSize | 組件最大尺寸 |
| palette | QPalette | 組件的調色板 |
| font | QFont | 組件使用的字體 |
| cursor | QCursor | 鼠標光標移到組件上的形狀 |
| mouseTracking | bool | 組件是否響應鼠標移動 |
| tabletTracking | bool | 組件是否響應平板追蹤 |
| focusPolicy | Qt::FocusPolicy | 組件的焦點策略 |
| contextMenuPolicy | Qt::ContextMenuPolicy | 組建的上下文菜單策略 |
| acceptDrops | bool | 組件是否接收拖動來的其他對象 |
| toolTip | QString | 鼠標移動到組件上時,顯示簡短提示 |
| statusTip | QString | 鼠標移動到組件上時,主窗口狀態欄顯示提示文字 |
| autoFillBackground | bool | 組件背景是否自動填充 |
| styleSheet | QString | 組建的樣式表 |
組件負責默認布局特性的sizePolicy是QSizePolicy類型,定義了組件在水平和垂直方向的尺寸變化策略.
為了訪問組件的sizePolicy,應當通過其Widget內部的sizePolicy()方法訪問.
QSizePolicy是一個枚舉類型,因而有以下枚舉常量:
- QSizePolicy::Fixed:固定尺寸,組件大小不改變
- QSizePolicy::Minimum:最小尺寸,使用sizeHint()的返回值或minimumuSize作為最小尺寸.
- QSizePolicy::Maximum:最大尺寸,使用sizeHint()的返回值或maximumuSize作為最大尺寸.
- QSizePolicy::Preferred:首選尺寸,組件仍然可以調整,但是放大時不會超過sizeHint()返回的尺寸.
- QSizePolicy::Expanding:可擴展尺寸,組件可擴展.
- QSizePolicy::MinimumExpanding:最小可擴展尺寸,綜合了可擴展尺寸與最小尺寸.
- QSizePolicy::Ignored:忽略尺寸,sizeHint()函數的返回值被忽略,組件占據盡可能大的空間.
在使用QSizePolicy的時候,QWidget的sizeHint()函數會起到很大作用.
在組件的父組件尺寸發生變化時,sizeHint()返回組件的建議尺寸.
一般不需要修改組件的sizePolicy屬性,使用其默認值即可.
部分部件的尺寸策略還進一步細分為水平策略與垂直策略
水平延伸因子與垂直延伸因子都是整數值,其取值范圍在0~255.
QWidget作為窗口時的屬性
| 屬性 | 屬性值類型 | 功能 |
|---|---|---|
| windowTitle | QString | 窗口標題欄的文字 |
| windowIcon | QIcon | 窗口標題上的圖表 |
| windowOpacity | qreal | 窗口的不透明度(范圍0.0~1.0) |
| windowFilePath | QString | 窗口相關的含路徑文件名 |
| windowModified | bool | 顯示窗口內文檔是否被修改(*) |
| windowModality | Qt::WindowModality | 窗口的模態,表示窗口是否在上層 |
| windowFlags | Qt::WindowFlags | 窗口的標志,是其一些值的組合 |
QWidget作為獨立的窗口時,實際上還有一些與窗口顯示有關的共用槽函數.
| 名稱 | 功能 |
|---|---|
| close() | 關閉窗口 |
| hide() | 隱藏窗口 |
| show() | 顯示窗口 |
| showFullScreen() | 以全屏方式顯示窗口 |
| showMaximized() | 窗口最大化 |
| showMinimized() | 窗口最小化 |
| showNormal() | 恢復正常窗口 |
布局管理
在Qt Designer的組件面板里有用于布局管理的兩組組件,Layouts與Spacers.
QLayout繼承自QObject與QLayoutItem.是Layouts中所有組件的基類.QLayout不是從QWidget繼承來的.
從QLayout繼承而來的幾個類是常用的布局管理類:
- QVBoxLayout:垂直布局
- QHBoxLayout:水平布局
- QGridLayout:網格布局,使組件按行與列網格狀布局
- QFormLayout:表單布局,與Grid相似,但只有兩列
- QStackedLayout:堆疊布局,用于管理多個頁面
任何布局類對象在可視化設計時都有layoutLeftMargin,layoutTopMargin,layoutRightMargin和layoutBottomMargin這個4個邊距屬性用于設置布局組件與父容器的4個邊距的最小值.
下面是一個調整邊距屬性值及layoutSpacing的例子:
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
this->windowTitle().clear();
this->setWindowTitle(QString("this is my window"));
QVBoxLayout* total_layout;
total_layout= new QVBoxLayout;
QGroupBox *btn_group;
btn_group= new QGroupBox(this);
btn_group->setGeometry(QRect(260,310,341,43));
QPushButton* btn_1,*btn_2,*btn_3;
btn_1= new QPushButton("button_1",btn_group);
btn_2= new QPushButton("button_2",btn_group);
btn_3= new QPushButton("button_3",btn_group);
QHBoxLayout* btn_layout;
btn_layout= new QHBoxLayout;
btn_layout->setSpacing(10);
btn_layout->setContentsMargins(15,25,5,5);
btn_layout->addWidget(btn_1);
btn_layout->addWidget(btn_2);
btn_layout->addWidget(btn_3);
total_layout->addLayout(btn_layout);
this->setLayout(total_layout);
}

在上面的例子中,所有的QPushButton都以QGroupBox為父對象.
使用QGroupBox::setGeometry()設置了組件的幾何形狀.
使用QHBoxLayout::setSpacing()設置了組件間的最小間距.
使用QHBoxLayout::setContentMargins()設置了四個邊距的值.
網格布局
可視化設計網格布局時一般是在一個容器組件內先擺放組件,使各組件的位置和大小與期望的效果大致相同,然后點擊工具欄上的網格布局按鈕進行網格布局.
除了4個邊距屬性,網格布局還有幾個特有的屬性:
- layoutHorizontalSpacing:水平方向上組件最小間距
- layoutVerticalSpacing:垂直方向上組件最小間距
- layoutRowStretch:各行的延展因子
- layoutColumnStretch:各列的延展因子
- layoutRowMinimumHeight:各行的最小高度,單位為像素
- layoutColumnMinimumWidth:各列的最小寬度,單位為像素
- layoutSizeConstraint:布局的尺寸限制方式
下面是應用網格布局應用的一個例子:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QGroupBox *groupBox=new QGroupBox(this);
groupBox->setGeometry(QRect(290,160,200,230));
QGridLayout *gridLayout=new QGridLayout(groupBox);
gridLayout->setHorizontalSpacing(7);
gridLayout->setVerticalSpacing(12);
gridLayout->setContentsMargins(10,10,-1,-1);
QPushButton *pushButton=new QPushButton(groupBox);
gridLayout->addWidget(pushButton,0,0,1,1);
QPushButton *pushButton_2=new QPushButton(groupBox);
gridLayout->addWidget(pushButton_2,0,1,1,1);
QComboBox *comboBox=new QComboBox(groupBox);
comboBox->addItem(QString());
gridLayout->addWidget(comboBox,1,0,1,2);
QPlainTextEdit *plainTextEdit=new QPlainTextEdit(groupBox);
gridLayout->addWidget(plainTextEdit,2,0,1,2);
this->setLayout(gridLayout);
}

其中,下面的語句表示將表格添加至0行0列,占據1行1列的位置.
gridLayout->addWidget(pushButton,0,0,1,1);
其他語句以此類推.
分割條布局
實現分割條功能的類是QSplitter,分隔條可以實現水平分割或垂直分割.一般是在兩個可以自由改變大小的組件間分割.
分割條主要有以下幾個屬性:
- orientation:方向,即水平分割或垂直分割
- opaqueResize:如果值為true,則拖動分割條時,組件是動態改變大小的.
- handleWidth:進行分割操作的拖動條的寬度,單位為像素.
- childrenCollapsible:表示進行分割操作時,子組件大小是否可以為0.
下面是一個使用分割條的例子:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSplitter *splitter=new QSplitter(this);
splitter->setOrientation(Qt::Horizontal);
splitter->setOpaqueResize(true);
splitter->setHandleWidth(8);
splitter->setMinimumSize(QSize(350,200));
splitter->setChildrenCollapsible(true);
QGroupBox *groupBox=new QGroupBox(splitter);
groupBox->setMinimumSize(QSize(10,0));
splitter->addWidget(groupBox);
QPlainTextEdit *plainTextEdit;
plainTextEdit=new QPlainTextEdit;
splitter->addWidget(plainTextEdit);
}


QChar字符
QChar是一個類,用于處理Qt中的字符.可以將其理解為一個加強版的char.
QChar有很多接口函數,常用的有:
- isDigital():是否為數字
- isLetter():是否為字母
- isLetterOrNumber():是否為字母或數字
- isLower():是否為小寫數字
- isUpper():是否為大寫數字
- isMark():是否為記號
- isNonCharacter():是否為非文字字符
- isNull():是否為'\0'
- isNumber():判斷字符是否為一個數,包括①之類的序號
- isPrint():判斷字符是否為可打印字符
- isPunct():判斷字符是否為標點符號
- isSpace():判斷字符是否為分割符號,如空格,制表符
- isSymbol():判斷字符是否為符號
- toLower():返回小寫形式
- toUpper():返回大寫形式
- (char16_t)unicode():返回16位編碼數值
其中值得注意的是一個靜態函數QChar::fromLatin1(),其用于將Latin1字符轉換為QChar字符.
與之對應的,QChar有一個toLatin1()函數用于將QChar字符轉換為Latin1字符.
提供一個使用例子:
QString str="String";
QChar ch=QChar::fromLatin1('Q');
str[0]=ch;
與之相似的,在QChar與UTF-16值轉換方面有unicode()方法與QChar::fromUsc2(char16_t c)函數.
QString字符串
QString是Qt中的一個類,用于存儲字符串.一般來說,Qt使用到字符串的地方都使用QString.
而一般的std::string與QString互轉需要通過QString::fromStdString(str)與qstr.toStdString().
QString是由QChar組成的一個串,QChar使用的是UTF-16編碼.
QString使用隱式共享來減少內存占用.這意味著只有在修改一個字符串的時候,這個字符串才會復制.
QString的創建與初始化
QString可以直接通過const char*初始化.
QString str="Hello World";
QString在被創建與初始化后,其存儲的就是一個QChar的字符數組.可以對其進行索引.
QString str="Hello";
QChar ch0=str[0];
QString字符串常用操作
可以使用加法運算符進行字符串拼接.
QString str1="Hello ";
QString str2="World";
Qstring str3=str1+str2;
也可以通過append()在字符串后添加字符串,通過prepend()在字符串前添加字符串.
QString str1="igg";
str1.preend(QString("n"));
str1.append(QString("a"));
front()返回第一個字符,back()返回最后一個字符.
left(n)返回前n個字符,right(n)返回后n個字符.注意:轉義符視為一個字符處理.
mid(pos,n)返回字符串中的字符數,pos為起始位置,n為返回字符的個數.
sliced()與mid()功能相同,但是其不判斷是否在邊界內.
函數section()用于從字符串中提取sep作為分隔符,從start段到end段的字符串.
例如:
QString str1="學生姓名,男,2004-09-15,漢族,湖南",str2;
str2=str1.section(",",0,0);//學生姓名
str2=str1.section(",",1,1);//男
str2=str1.section(",",1,2);//男,2004-09-15
str2=str1.section(",",4,4);//湖南
isNull()和isEmpty()作用相似,但是isNull()會對'\0'進行判定,而isEmpty()判定'\0'為true.
QString str1="",str2;
str1.isNull();//false
str1.isEmpty();//true
str2.isNull();//true
str2.isEmpty();//true
count(),若帶有參數,可以統計某個字符在字符串中出現的次數.若不帶參數,count(),size()與length()都返回字符串長度.
clear()函數清空當前字符串,使字符串為NULL.
resize()用于改變字符串長度,但如果長度短于當前字符串則會截斷;長度長于當前字符串則會導致未初始化的內存.
如果resize內含有參數,那么則使用該QChar填充字符串填充部分.
與resize()不同,函數fill()則將字符串中每個字符都用一個新字符替換.其同樣可以通過參數調整字符串長度.
indexOf()與lastIndexOf()的功能是在字符串內查找某個字符串首次與最后一次出現的位置.
contains()判斷當前字符串是否包含某個字符串.可通過Qt::CaseInsensitive表示是否分辨大小寫.
endsWith()和startWith()判斷字符串是否以某個字符串開頭或結尾.
count()用于統計當前字符串中某個字符串出現的次數.可以設置Qt::CaseInsensitive是否分辨大小寫.
函數toUpper()和toLower()用于將字符串內的字母全部轉換為大寫字母或小寫字母.
trimmed()和simplified(),trimmed()會去掉字符串首尾的空格,函數simplified()不僅去掉首尾空格,還會將中間的連續空格用單個空格替換.
chop(n)去掉字符串末尾的n個字符,如果n大于實際意義,字符串內容就變為空.
insert(pos,str),函數insert用于在某個位置插入一個字符串.如果pos大于實際意義,字符串會自動補充空格填充.
replace(pos,n,after)用于從某個位置開始替換n個字符.
其還有一種形式replace(before,after)用于替換所有before字符串為after.可以指定Qt::CaseInsensitive分辨大小寫.
remove(pos,n)的功能為從字符串pos開始的位置移出n個字符.若超出實際意義,則把pos后面的字符都移除.
同樣的,其還有另一種參數模式,remove(ch),即移除字符串中某個字符出現的所有實例.
QString字符串與數值轉換
QString有一些接口函數用于將字符串轉換為整數:
參數ok用于獲取返回值,表示轉換是否成功.
- toInt(bool* ok,int base=10)
- toUInt(bool* ok,int base=10)
- toLong(bool* ok,int base=10)
- toUInt(bool* ok,int base=10)
- toShort(bool* ok,int base=10)
- toUShort(bool* ok,int base=10)
- toLongLong(bool* ok,int base=10)
- toULongLong(bool* ok,int base=10)
其也還有兩個接口函數用于將字符串轉換為浮點數:
- toFloat(bool* ok)
- toDouble(bool* ok)
函數setNum()則用于將整數或浮點數轉換為字符串.
- setNum(int n,int base=10)
- setNum(float n,char format='g',int precision=6)
| 格式字符 | 格式字符含義 | 精度位數含義 |
|---|---|---|
| e,E | 科學計數法 | 基數小數點后位數 |
| f | 自然計數法 | 小數點后的有效位數 |
| g,G | 根據情況自動調節 | 小數點前后的數字位數之和 |
QString還有一個靜態函數number(),其與setNum類似,但是是靜態函數形式
- QString::number(long n,int base)
- QString::number(double n,char format,precision)
靜態函數asprintf()用于構造格式化輸出字符串.
- QString QString::asprintf(const char cformat*,...)
但是注意,asprintf輸出%s會導致亂碼,只能使用UTF-8編碼的const char*字符串來作為參數.
也就是說,QString型的字符串應當通過QString::data()來表現.
例如:
QString str1=QString::asprintf("Year=%d,Month=%02d",2024,04);
QString str2="哈爾濱工程大學 拓荒者學社"
QString str3=QString::asprintf("歡迎來到%s",str2.toLocal8Bit().data());
QString str4=QString::asprintf("PI=%.10f",M_PI);//3.1415926536
arg()函數是QString的成員函數,用于格式化輸出各種數據的字符串,其功能與asprintf類似.
但是arg函數通過形式為%n的占位符來對應實參,這與一般printf不同.
int year=2024,month=2,day=23;
QString str=QString("%1年,%2月,%3日").arg(year).arg(month).arg(day);
QSpinBox和QDoubleSpinBox
| 屬性名稱 | 功能 |
|---|---|
| prefix | 數字顯示的前綴 |
| suffix | 數字現實的后綴 |
| buttonSysbols | 右側調節按鈕的符號 |
| text | 只讀屬性,SpinBox內的所有文字 |
| cleanText | 只讀屬性,不帶前后綴的所有文字 |
| minimum | 數值范圍的最小值 |
| maximum | 數值范圍的最大值 |
| singleStep | 單步步長改變值 |
| stepType | 步長類型,單一步長或自適應步長 |
| value | 當前顯示的值 |
| displayIntegerBase | QSpinBox使用的進制 |
| decimals | QDoubleSpinBox顯示的小數位數 |
對于默認值value的相關操作,存在兩個相關的函數:
- int QSpinBox::value()
- void QSpinBox::setValue(int val)
對于相關的讀寫范圍,還有一個函數setRange(),用于同時設置最小值與最大值.
- void QSpinBox::setRange(int minimum,int maximum)
QSpinBox還有兩個特有的信號,信號定義如下:
- void QSpinBox::valueChanged(int i)
- void QSpinBox::textChanged(const QString &text)
信號valueChanged()在value變化時被發射,傳遞的參數為變化之后的數值.
信號textChanged()在顯示的文字發生變化的時候被發射.
下面是使用QSpinBox的一個實例:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
//ui->setupUi(this);
lbTest1= new QLabel(QString("電源電動勢"));
lbTest2= new QLabel(QString("反應物濃度"));
lbTest3= new QLabel(QString("十六進制值測試"));
sbTest1= new QSpinBox;
sbTest2= new QSpinBox;
sbTest3= new QSpinBox;
sbTest1->setSuffix(QString("mV"));
sbTest1->setValue(10);
sbTest2->setSuffix(QString("mod/L"));
sbTest2->setValue(1);
sbTest3->setSuffix(QString("值"));
sbTest3->setValue(28);
sbTest3->setDisplayIntegerBase(16);
txlTest= new QLineEdit;
txlTest->setText(QString("這里會顯示內容"));
connect(sbTest1,SIGNAL(valueChanged(int)),this,SLOT(SpinBoxToLineEdit(int)));
QGridLayout* gridTest= new QGridLayout;
gridTest->addWidget(lbTest1,0,0,1,1);
gridTest->addWidget(lbTest2,1,0,1,1);
gridTest->addWidget(lbTest3,3,0,1,1);
gridTest->addWidget(sbTest1,0,1,1,1);
gridTest->addWidget(sbTest2,1,1,1,1);
gridTest->addWidget(sbTest3,3,1,1,1);
gridTest->addWidget(txlTest,2,0,1,2);
this->setLayout(gridTest);
}
void Widget::SpinBoxToLineEdit(int i)
{
this->txlTest->clear();
this->txlTest->insert(QString("電源電動勢改變后:%1").arg(i));
return;
}

常用的按鈕控件
按鈕是界面上常用的組件,常用的4種按鈕控件是:普通按鈕(QPushButton),工具按鈕(QToolButton),單選按鈕(QRadioButton),復選框(QCheckBox)
這四種按鈕都是繼承于QAbstractButton類的.
| 屬性 | 屬性值類型 | 功能 |
|---|---|---|
| text | QString | 按鈕的顯示文字 |
| icon | QIcon | 按鈕的圖標 |
| shortcut | QKeySequence | 按鈕的快捷鍵 |
| checkable | bool | 按鈕是否可復選 |
| checked | bool | 按鈕是否復選狀態 |
| autoExclusive | bool | 在一個布局或容器組件內的同類按鈕是否互斥 |
| autoRepeat | bool | 是否自動重復發射信號 |
- QPushButton的checkable默認為false
- QRadioButton和QCheckBox的checkable屬性默認為true
- QCheckBox的autoExclusive屬性默認為false
- QRadioButton的autoExclusive屬性默認為true
| 屬性 | 屬性值類型 | 功能 |
|---|---|---|
| autoDefault | bool | 按鈕是否為自動默認按鈕 |
| default | bool | 按鈕是否為默認按鈕 |
| flat | bool | 按鈕是否沒有邊框 |
QCheckBox新增了一個tristate屬性,QRadioButton沒有新的屬性.
QAbstractButton定義的新信號:
- void clicked(bool checked)//點擊按鈕時
- void pressed()//按下空格或左鍵
- void released()//釋放空格或左鍵
- void toggled(bool checked)//按鈕的checked屬性變化
QPushButton和QRadioButton沒有定義新信號.
QCheckBox定義了一個新信號:
- void QCheckBox::stateChanged(int state)
下面提供了一個使用button的例子:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void on_btnLeft();
void on_btnMiddle();
void on_btnRight();
void on_btnBF();
void on_btnIT();
void on_btnUL();
void on_chkRead(bool checked);
void on_chkEnabled(bool checked);
void on_chkClean(bool checked);
void on_radBlack();
void on_radBlue();
void on_radRed();
signals:
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->btnLeft,SIGNAL(clicked(bool)),this,SLOT(on_btnLeft()));
connect(ui->btnRight,SIGNAL(clicked(bool)),this,SLOT(on_btnRight()));
connect(ui->btnMiddle,SIGNAL(clicked(bool)),this,SLOT(on_btnMiddle()));
connect(ui->btnBF,SIGNAL(clicked(bool)),this,SLOT(on_btnBF()));
connect(ui->btnIT,SIGNAL(clicked(bool)),this,SLOT(on_btnIT()));
connect(ui->btnUL,SIGNAL(clicked(bool)),this,SLOT(on_btnUL()));
connect(ui->radBlack,SIGNAL(clicked(bool)),this,SLOT(on_radBlack()));
connect(ui->radBlue,SIGNAL(clicked(bool)),this,SLOT(on_radBlue()));
connect(ui->radRed,SIGNAL(clicked(bool)),this,SLOT(on_radRed()));
connect(ui->chkClean,SIGNAL(clicked(bool)),this,SLOT(on_chkClean(bool)));
connect(ui->chkEnabled,SIGNAL(clicked(bool)),this,SLOT(on_chkEnabled(bool)));
connect(ui->chkRead,SIGNAL(clicked(bool)),this,SLOT(on_chkRead(bool)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnLeft()
{
ui->pltEdit->setAlignment(Qt::AlignLeft);
}
void MainWindow::on_btnMiddle()
{
ui->pltEdit->setAlignment(Qt::AlignCenter);
}
void MainWindow::on_btnRight()
{
ui->pltEdit->setAlignment(Qt::AlignRight);
}
void MainWindow::on_btnBF()
{
static bool flag=true;
QFont font= ui->pltEdit->font();
font.setBold(flag);
ui->pltEdit->setFont(font);
flag=!flag;
}
void MainWindow::on_btnIT()
{
static bool flag=true;
QFont font= ui->pltEdit->font();
font.setItalic(flag);
ui->pltEdit->setFont(font);
flag=!flag;
}
void MainWindow::on_btnUL()
{
static bool flag=true;
QFont font= ui->pltEdit->font();
font.setUnderline(flag);
ui->pltEdit->setFont(font);
flag=!flag;
}
void MainWindow::on_chkRead(bool checked)
{
ui->pltEdit->setReadOnly(checked);
}
void MainWindow::on_chkEnabled(bool checked)
{
ui->pltEdit->setEnabled(checked);
}
void MainWindow::on_chkClean(bool checked)
{
ui->pltEdit->setClearButtonEnabled(checked);
}
void MainWindow::on_radBlack()
{
QPalette plet= ui->pltEdit->palette();
plet.setColor(QPalette::Text,Qt::black);
ui->pltEdit->setPalette(plet);
}
void MainWindow::on_radBlue()
{
QPalette plet= ui->pltEdit->palette();
plet.setColor(QPalette::Text,Qt::blue);
ui->pltEdit->setPalette(plet);
}
void MainWindow::on_radRed()
{
QPalette plet= ui->pltEdit->palette();
plet.setColor(QPalette::Text,Qt::red);
ui->pltEdit->setPalette(plet);
}

QSlider和QProgressBar
QAbstractSlider是QSlider,QScrollBar和QDial的父類,它定義了這幾個類共有的一些屬性和接口函數.
| 屬性 | 屬性值類型 | 功能 |
|---|---|---|
| minimum | int | 數據范圍的最小值 |
| maximum | int | 數據范圍的最大值 |
| singleStep | int | 變化最小步長 |
| pageStep | int | 按PgUp與PgDn變化的數值 |
| value | int | 組件的當前值 |
| sliderPosition | int | 滑塊的位置 |
| tracking | bool | 改變value是否改變slider位置 |
| orientation | Qt::Orientation | 滑動條的方向,水平或垂直 |
| invertedAppearance | bool | 顯示方式是否反向 |
| invertedControls | bool | 反向按鍵控制 |
QAbstractSlider的接口函數主要是屬性的讀寫函數,還有一個常用函數setRange()用于設置最大值與最小值.
- void QAbstractSlider::setRange(int min,int max)
QAbstractSlider類的信號主要有:
- void actionTriggered(int action)//滑動條觸發一些動作
- void rangeChanged(int min,int max)//minimum或maximum值變化時
- void sliderMoved(int value)//用戶按住鼠標拖動滑塊時
- void sliderPressed()//在滑塊上按下鼠標時
- void sliderReleased()//在滑塊上釋放鼠標時
- void valueChanged(int value)//value值改變時
action表示動作的類型,用枚舉類型QAbstractSlider::SliderAction的值表示.如SliderToMinimum表示拖動到最小值.
如果tracking屬性被設置為false時,valueChanged()僅在鼠標拖動結束時發射.
QSlider一般用于滑動輸入數值數據的組件,其新定義的屬性有兩個:
- tickPosition:標尺刻度的顯示位置,屬性值為枚舉類型QSlider::TickPosition.
- tickInterval:標尺刻度的間隔值.
QScrollBar沒有新定義的屬性,一般與文本編輯器或容器組件組合使用.起滾卷條的作用.
QDial表示表盤式組件,通過旋轉表盤獲得輸入值.QDial定義了3個新的屬性:
- notchesVisible:表盤外圍的刻度線是否可見.
- notchTarget:表盤刻度間的間隔像素值.
- wrapping:表盤上首尾刻度是否連貫.
QProgressBar表示進度條組件,一般以百分比數據來顯示進度.其父類為QWidget.
其幾個不易理解的屬性如下:
- textDirection:文字的方向.
- format:顯示文字的格式.
QProgressBar類的接口函數主要是屬性的讀寫函數.QProgressBar還有兩個常用的與屬性無關的函數:
- void QProgressBar::setRange(int minimum,int maximum)
- void QProgressBar::reset()
下面是一個使用滾動條的實例:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->dial,SIGNAL(valueChanged(int)),this,SLOT(do_valueChange(int)));
connect(ui->progressBar,SIGNAL(valueChanged(int)),this,SLOT(do_valueChange(int)));
connect(ui->scrollBar,SIGNAL(valueChanged(int)),this,SLOT(do_valueChange(int)));
connect(ui->slider,SIGNAL(valueChanged(int)),this,SLOT(do_valueChange(int)));
connect(ui->spinBox,SIGNAL(valueChanged(int)),this,SLOT(do_valueChange(int)));
ui->dial->setNotchesVisible(true);
do_valueChange(10);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::do_valueChange(int value)
{
ui->dial->setValue(value);
ui->progressBar->setValue(value);
ui->scrollBar->setValue(value);
ui->slider->setValue(value);
ui->spinBox->setValue(value);
}

日期時間數據
日期和時間是經常遇到的數據類型.Qt提供了三個類用于表示和處理數據類型:
- QTime:表示時間數據的類.
- QDate:表示日期數據的類.
- QDateTime:表示時間和日期數據的類.
這三個類都沒有父類.為了在界面上輸入和現實日期時間的數據,Qt定義了幾個用于日期時間數據處理的界面類:
- QTimeEdit:編輯和顯示時間的組件類
- QDateEdit:編輯和顯示日期的組件類
- QDateTimeEdit:編輯和顯示日期的組件類.
- QCalendarWidget:一個用日歷形式顯示和選擇日期的組件類.
QTime類適用于存儲與操作時間數據的類,時間數據包含小時,分鐘,秒,毫秒.QTime總是24小時制,不區分AM/PM.
QTime初始化時間數據的函數定義如下:
- QTime::QTime(int h,int m,int s=0,int ms=0)
還可以使用靜態函數QTime::currentTime()創建一個QTime對象,并將其初始化為系統當前時間.
| 函數原型 | 功能 |
|---|---|
| int hour() | 返回當前時間的小時 |
| int minute() | 返回當前時間的分鐘 |
| int second() | 返回當前時間的秒 |
| int misec() | 返回當前時間的毫秒 |
| bool setHMS(int h,int m,int s,int ms=0) | 設置當前時間的數據 |
| int msecSinceStartOfDay() | 返回時間從00:00:00開始的毫秒數 |
| QTime addSecs(int s) | 當前時間延后s秒后的時間 |
| int secsTo(QTime t) | 返回一個與當前時間相差t秒的秒數 |
| QString toString(const QString& format) | 將當前時間按照format格式轉換為字符串 |
QDate是用于存儲和操作日期數據的類,日期數據包含年月日數據.
與QTime類似,可以在初始化時為其提供數據,也可以使用靜態函數QDate::currentDate()獲取系統當前日期.
| 函數原型 | 功能 |
|---|---|
| int year() | 返回當前日期年數據 |
| int month() | 返回當前日期月數據 |
| int day() | 返回當前日期日數據 |
| int dayOfWeek() | 返回當前日期在一周中的日期 |
| int dayOfYear() | 返回當前日期在一年中是第多少天 |
| bool setDate(int year,int month,int day) | 設置日期的年日月數據 |
| void getDate(int* year,int* month,int* day) | 通過指針變量,返回年日月數據 |
| QDate addYears(int nyears) | 返回一個較時間遲n年的QDate變量 |
| QDate addMonths(int nmonths) | 返回一個較時間遲n月的QDate變量 |
| QDate addDays(qint64 ndays) | 返回一個較時間遲n天的QDate變量 |
| qint64 daysTo(QDate d) | 返回一個與當前日期差d天的天數 |
| QString toString(const QString&format) | 將當前日期按照format格式轉換為字符串 |
此外,QDate還有一個靜態函數isLeapYear()可以判斷某年是否為閏年:
- bool QDate::isLeapYear(int year)
| 函數原型 | 功能 |
|---|---|
| QDate date() | 返回當前日期時間數據的日期數據 |
| QTime time() | 返回當前日期時間數據的時間數據 |
| qint64 toMSecsSinceEpoch() | 返回與UTC時間1970-01-01T00:00:00:00.000相差的毫秒數 |
| void setMSecsSinceEpoch(qint64 msecs) | 設置與UTC時間1970-01-01T00:00:00:00.000相差的毫秒數 |
| qint64 toSecsSinceEpoch() | 返回與UTC時間1970-01-01T00:00:00:00.000相差的秒數 |
| void setSecsSinceEpoch(qint64) | 設置與UTC時間1970-01-01T00:00:00:00.000相差的秒數 |
| QString toString(const QString& format) | 將當前日期時間按照format設置的格式轉換為字符串 |
| QDateTime toUTC() | 將當前時間轉換為UTC時間 |
QDateTime有兩個靜態函數用于返回系統當前時間:
- QDateTime QDateTime::currentDateTime()
- QDateTime QDateTime::currentDateTimeUtc()
QTime,QDate,QDateTime都有一個函數toString(),用于將當前的日期時間數據轉換為字符串.
同樣的,QTime,QDate,QDateTime都有一個靜態函數fromString().用于將字符串轉換為相應類的對象.
- QString QDateTime::toString(const QString&format,QCalendar cal=QCalendar())
- QDateTime QDateTime::fromString(const QString&string,const QString&format,QCalendar cal=QCalendar())
| 格式字符 | 含義 |
|---|---|
| d | 天1~31 |
| dd | 天01~31 |
| M | 月1~12 |
| MM | 月01~12 |
| yy | 年00~99 |
| yyyy | 年0000~9999 |
| h | 小時023或112 |
| hh | 小時0023或0112 |
| H | 小時0~23 |
| HH | 小時00~23 |
| m | 分鐘0~59 |
| mm | 分鐘00~59 |
| s | 秒0~59 |
| ss | 秒00~59 |
| z | 毫秒0~999 |
| zzz | 毫秒000~999 |
| AP或A | 使用AM/PM顯示 |
| ap或a | 使用am/pm顯示 |
而且上述字符僅作為一個占位符使用,其其他內容不影響其字符串format.
QtDesigner有3個用于編輯日期時間數據的界面組件,如QTimeEdit,QDateEdit,QDateTimeEdit.
而QDateTimeEdit是QDateEdit和QTimeEdit的父類,而QDateTimeEdit的父類是QAbstractSpinBox.
所以其實日期時間編輯框的特性與QSpinBox的有些相似.
QDateTimeEdit的主要屬性有:
- currentSection:光標所在的輸入段,是枚舉類型QDateTimeEdit::Section.
- currentSecitonIndex:用序號表示的光標所在的段.
- calendarPopup:是否允許彈出一個日歷選擇框.會將上下調節按鈕變成一個下拉按鈕.
- displayFormat:日期時間數據的顯示格式.
QDateTimeEdit常用的接口函數就是讀取或設置日期時間數據的函數:
- QDateTime dateTime()
- void setDateTime(const QDateTime&dateTime)
- QDate date()
- void setDate(QDate date)
- QTime time()
- void setTime(QTime time)
QDateTimeEdit有3個信號:
- void dateChanged(QDate date)
- void timeChanged(QTime time)
- void dateTimeChanged(const QDateTime& datetime)
QCalendarWidget則是一個用于選擇日期的日歷組件.
QCalendarWidget的幾個常見接口函數有:
- void showToday()
- void showSelectedDate()
- QDate selectedDate()
- void setSelectedDate(QDate date)
QCalendarWidget有4個信號:
- void activated(QDate date)
- void clicked(QDate date)
- void currentPageChanged(int year,int month)
- void selectionChanged()
選擇的日期變化時,QCalendarWidget會發射selectionChanged信號.
下面給出了一個使用QDateTime,QCalendarWidget等的例子:
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void on_btnReset();
void on_btnClear();
void on_btnTime();
void on_btnDate();
void on_btnDateTime();
void on_btnChange();
void on_timeEdit();
void on_dateEdit();
void on_dateTimeEdit();
void on_calendar();
};
#endif // MAINWINDOW_H
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->btnClear,SIGNAL(clicked(bool)),this,SLOT(on_btnClear()));
connect(ui->btnReset,SIGNAL(clicked(bool)),this,SLOT(on_btnReset()));
connect(ui->btnTime,SIGNAL(clicked(bool)),this,SLOT(on_btnTime()));
connect(ui->btnDate,SIGNAL(clicked(bool)),this,SLOT(on_btnDate()));
connect(ui->btnDateTime,SIGNAL(clicked(bool)),this,SLOT(on_btnDateTime()));
connect(ui->btnChange,SIGNAL(clicked(bool)),this,SLOT(on_btnChange()));
connect(ui->dateEdit,SIGNAL(dateChanged(QDate)),this,SLOT(on_dateEdit()));
connect(ui->timeEdit,SIGNAL(timeChanged(QTime)),this,SLOT(on_timeEdit()));
connect(ui->dateTimeEdit,SIGNAL(dateTimeChanged(QDateTime)),this,SLOT(on_dateTimeEdit()));
connect(ui->calendar,SIGNAL(selectionChanged()),this,SLOT(on_calendar()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnReset()
{
ui->calendar->clearFocus();
ui->dateEdit->clear();
ui->timeEdit->clear();
ui->dateTimeEdit->clear();
ui->pltEdit->clear();
ui->lineEdit->clear();
}
void MainWindow::on_btnClear()
{
ui->lineEdit->clear();
ui->pltEdit->clear();
}
void MainWindow::on_btnTime()
{
QTime TM1(13,24,5);
QString str=TM1.toString("HH:mm:ss");
ui->pltEdit->appendPlainText(QString("Time1:%1").arg(str));
QTime TM2= TM1.addSecs(150);
str= TM2.toString("HH:mm:ss");
ui->pltEdit->appendPlainText(QString("Time1 add 150secs:%1").arg(str));
TM2= QTime::currentTime();
str=TM2.toString("HH:mm:ss zzz");
ui->pltEdit->appendPlainText(QString("Current Time:%1").arg(str));
}
void MainWindow::on_btnDate()
{
QDate DT1(2021,7,6);
QString str=DT1.toString("yyyy-MM-dd");
ui->pltEdit->appendPlainText(QString("Date1:%1").arg(str));
QDate DT2;
DT2.setDate(2021,8,25);
str=DT2.toString("yyyy-MM-dd");
ui->pltEdit->appendPlainText(QString("Date2:%1").arg(str));
DT2=QDate::currentDate();
str=DT2.toString("yyyy-MM-dd");
ui->pltEdit->appendPlainText(QString("Current Date:%1").arg(str));
}
void MainWindow::on_btnDateTime()
{
QDateTime DT1=QDateTime::currentDateTime();
QString str=DT1.toString("yyyy-MM-dd hh:mm:ss zzz");
ui->pltEdit->appendPlainText(QString("Current DateTime:%1").arg(str));
QDate dt= DT1.date();
str=dt.toString("yyyy-MM-dd");
ui->pltEdit->appendPlainText(QString("DT1 Date:%1").arg(str));
QTime tm=DT1.time();
str=tm.toString("hh:mm:ss zzz");
ui->pltEdit->appendPlainText(QString("DT1 Time:%1").arg(str));
qint64 MS=DT1.toSecsSinceEpoch();
ui->pltEdit->appendPlainText(QString("Secs Since:%1").arg(MS));
MS+=120;
DT1.setSecsSinceEpoch(MS);
str=DT1.toString("yyyy-MM-dd hh:mm:ss zzz");
ui->pltEdit->appendPlainText(QString("DT1 After120s:%1").arg(str));
}
void MainWindow::on_btnChange()
{
static bool calendar_flag=true;
ui->dateTimeEdit->setCalendarPopup(calendar_flag);
calendar_flag=!calendar_flag;
}
void MainWindow::on_timeEdit()
{
QTime tm= ui->timeEdit->time();
ui->dateTimeEdit->setTime(tm);
}
void MainWindow::on_dateEdit()
{
QDate dt= ui->dateEdit->date();
ui->lineEdit->setText(QString("%1").arg(dt.toString("yyyy-MM-dd")));
ui->dateTimeEdit->setDate(dt);
ui->calendar->setSelectedDate(dt);
ui->calendar->showSelectedDate();
}
void MainWindow::on_dateTimeEdit()
{
QDateTime datetime= ui->dateTimeEdit->dateTime();
ui->lineEdit->setText(QString("%1").arg(datetime.date().toString("yyyy-MM-dd")));
ui->dateEdit->setDate(datetime.date());
ui->timeEdit->setTime(datetime.time());
ui->calendar->setSelectedDate(datetime.date());
ui->calendar->showSelectedDate();
ui->pltEdit->appendPlainText(QString("Now Time:%1").arg(datetime.toString("yyyy-MM-dd hh:mm:ss zzz")));
}
void MainWindow::on_calendar()
{
QDate dt=ui->calendar->selectedDate();
ui->dateEdit->setDate(dt);
ui->dateTimeEdit->setDate(dt);
ui->lineEdit->setText(dt.toString("yyyy-MM-dd"));
}

QTimer和QElapsedTimer
QTimer是軟件計時器,其父類是QObject.其主要功能是設置以毫秒為單位的定時周期.
當定時器啟動后,定時溢出時QTimer發射timeout()信號.
QTimer類的主要屬性如下:
| 屬性 | 屬性值類型 | 功能 |
|---|---|---|
| interval | int | 定時周期,單位是毫秒 |
| singleShot | bool | 定時器是否為單次計時 |
| timerType | Qt::TimerType | 定時器精度類型 |
| active | bool | 返回定時器是否正在運行 |
| remainingTime | int | 到發生定時溢出的剩余時間 |
屬性timeType表示定時器的精度類型,設置函數setTimerType()的原型定義如下:
- void QTimer::setTimerType(Qt::TimerType atype)
參數atype是枚舉類型Qt::TimerType,有以下幾個枚舉值,默認為Qt::CoarseTimer:
- Qt::PreciseTimer:精確計時器,精度保持在毫秒級
- Qt::CoarseTimer:粗糙計時器,定時誤差保持在周期值的5%內
- Qt::VeryCoarseTimer:非常粗糙的定時器,精度保持在秒級.
QTimer有幾個公有槽函數用于啟動和停止定時器:
- void QTimer::start()//啟動定時器
- void QTimer::start(int msec)//啟動定時器,并設置定時周期
- void QTimer::stop()//停止定時器
QTimer只有一個timeout()信號,其原型如下:
- void QTimer::timeout()
QTimer還有一個靜態函數singleShot(),用于創建和啟動單次定時器,并且將定時器的timeout()信號與指定的槽函數關聯.
這個函數有多種參數形式,其中一種函數原型定義如下:
- void QTimer::singleShot(int msec,Qt::TimerType,const QObject* receiver,const char* member)
QElapsedTimer則用于快速計算兩個時間的間隔時間,它沒有父類,不支持Qt的元對象系統,所以只有接口函數.
QElapsedTimer的接口函數有:
- void start()
- qint64 elapsed()
- qint64 nsecsElapsed()
- qint64 restart()
函數elapsed()的返回值是自上次start()之后計時器的運行時間,單位是毫秒.
函數nsecsElapsed()的返回值也是指上次start()之后計時器的運行時間,但單位是納秒.
函數restart()返回從上次啟動計時器到現在的時間,單位是毫秒,然后重啟計時器.
下面是一個使用QTimer的實例:
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTime>
#include <QTimer>
#include <QElapsedTimer>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QTimer* m_timer;
QElapsedTimer m_counter;
private slots:
void do_timer_timeout();
void do_timer_shot();
void do_btnStart();
void do_btnStop();
void do_btnOneShot();
};
#endif // MAINWINDOW_H
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_timer= new QTimer(this);
m_timer->stop();
m_timer->setTimerType(Qt::CoarseTimer);
ui->radCoarse->setChecked(true);
connect(m_timer,SIGNAL(timeout()),this,SLOT(do_timer_timeout()));
connect(ui->btnStart,SIGNAL(clicked(bool)),this,SLOT(do_btnStart()));
connect(ui->btnStop,SIGNAL(clicked(bool)),this,SLOT(do_btnStop()));
connect(ui->btnOneShot,SIGNAL(clicked(bool)),this,SLOT(do_btnOneShot()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::do_timer_timeout()
{
QApplication::beep();
QTime curTime= QTime::currentTime();
ui->LCDHour->display(curTime.hour());
ui->LCDMin->display(curTime.minute());
ui->LCDSec->display(curTime.second());
if(m_timer->isSingleShot()){
int tmMsec= m_counter.elapsed();
QString str=QString("流逝的時間:%1毫秒").arg(tmMsec);
ui->labelTime->setText(str);
ui->btnStop->setEnabled(false);
}
}
void MainWindow::do_timer_shot()
{
QApplication::beep();
int tmMsec= m_counter.elapsed();
QString str=QString("流逝的時間:%1毫秒").arg(tmMsec);
ui->labelTime->setText(str);
ui->btnOneShot->setEnabled(true);
}
void MainWindow::do_btnStart()
{
m_timer->setInterval(ui->spinBox->value());
if(ui->radCoutinue->isChecked())
m_timer->setSingleShot(false);
else
m_timer->setSingleShot(true);
if(ui->radPrecise->isChecked())
m_timer->setTimerType(Qt::PreciseTimer);
else if(ui->radCoutinue->isChecked())
m_timer->setTimerType(Qt::CoarseTimer);
else
m_timer->setTimerType(Qt::VeryCoarseTimer);
m_timer->start();
m_counter.start();
ui->btnStart->setEnabled(false);
ui->btnOneShot->setEnabled(false);
ui->btnStop->setEnabled(true);
}
void MainWindow::do_btnStop()
{
m_timer->stop();
int tmMsec= m_counter.elapsed();
int ms= tmMsec%1000;
int sec= tmMsec/1000;
QString str= QString("流逝的時間:%1秒%2毫秒").arg(sec).arg(ms,3,10,QChar('0'));
ui->labelTime->setText(str);
ui->btnStart->setEnabled(true);
ui->btnOneShot->setEnabled(true);
ui->btnStop->setEnabled(false);
}
void MainWindow::do_btnOneShot()
{
int intv= ui->spinBox->value();
QTimer::singleShot(intv,Qt::PreciseTimer,this,&MainWindow::do_timer_shot);
m_counter.start();
ui->btnOneShot->setEnabled(false);
}

QComboBox
QComboBox是下拉列表框組件,它可以提供下拉列表供用戶選擇輸入,也可以提供編輯框用于輸入文字.
所以QComboBox也被稱為組合框.
| 屬性 | 屬性值類型 | 功能 |
|---|---|---|
| editable | bool | 是否可編輯,若為false則只可使用下拉欄 |
| currentText | QString | 當前顯示的文字 |
| currentIndex | int | 當前選中項的序號 |
| maxVisibleItems | int | 下拉列表中顯示最大條數,若超過將出現卷滾條 |
| maxCount | int | 下拉列表中最大項數 |
| insertPolicy | InsertPolicy | 用戶編輯的新文字插入列表的方式,為枚舉類型QComboBox::InsertPolicy |
| placeholderText | QString | 占位文字 |
| duplicatesEnabled | bool | 是否允許列表中出現重復的項 |
| modelColumn | int | 下拉列表中的數據在數據模型中的列編號 |
QComboBox使用模型/視圖結構存儲和顯示下拉列表的數據,下拉列表的數據實際上存儲在QStandardItemModel模型里.下拉列表使用QListView的子類組件顯示.modelColumn屬性表示下拉列表現實的數據在模型中的列編號.
QComboBox的幾個信號原型如下:
- void activated(int index)
- void currentIndexChanged(int index)
- void currentTextChanged(const QString &text)
- void editTextChanged(const QString &text)
- void highlighted(int index)
- void textActivated(const QString &text)
- void textHighlighted(const QString &text)
下面是使用QComboBox的一個實例:
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
//void on_btnSimpleInit();
void on_pushButton_5_clicked(bool checked);
void on_btnSimpleInit_clicked(bool checked);
void on_chkEditable_clicked(bool checked);
void on_btnClearList_clicked(bool checked);
void on_btnDataInit_clicked(bool checked);
void comChanged(const QString& arg1);
void on_comData_currentIndexChanged(int index);
void on_chkReadOnly_clicked(bool checked);
};
#endif // MAINWINDOW_H
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_5_clicked(bool checked)
{
ui->pltEdit->clear();
}
void MainWindow::on_btnSimpleInit_clicked(bool checked)
{
QIcon icon;
icon.addFile(":/img/icon.jpg");
ui->comSimple->clear();
for(int i=0;i<20;i++)
ui->comSimple->addItem(icon,QString("城市%1").arg(i));
}
void MainWindow::on_chkEditable_clicked(bool checked)
{
ui->comSimple->setEditable(checked);
}
void MainWindow::on_btnClearList_clicked(bool checked)
{
ui->comSimple->clear();
}
void MainWindow::on_btnDataInit_clicked(bool checked)
{
ui->comData->clear();
QMap<QString,int>city_zone;
city_zone.insert(QString("北京"),10);
city_zone.insert(QString("上海"),20);
city_zone.insert(QString("廣州"),30);
city_zone.insert(QString("長沙"),40);
city_zone.insert(QString("成都"),50);
for(auto iter:city_zone.keys())
ui->comData->addItem(iter,city_zone.value(iter));
}
void MainWindow::comChanged(const QString &arg1)
{
ui->pltEdit->appendPlainText(arg1);
}
void MainWindow::on_comData_currentIndexChanged(int index)
{
Q_UNUSED(index);
QString str= ui->comData->currentText()+ui->comData->currentData().toString();
ui->pltEdit->appendPlainText(str);
}
void MainWindow::on_chkReadOnly_clicked(bool checked)
{
ui->pltEdit->setEnabled(!checked);
}

QMainWindow和QAction
QMainWindow是主窗口類,具有菜單欄,工具欄,狀態欄等主窗口常見的界面元素.
要設計主窗口上的菜單欄,工具欄,按鈕的下拉菜單,組建的快捷菜單等需要用到QAction類.
窗口界面可視化設計
創建一個GUI項目,在向導中選擇窗口基類為QMainWindow,新建窗口類的名稱會被自動設置為MainWindow.
QAction的父類是QObject,所以支持Qt的元對象系統.在UI可視化設計時就可以創建Action,使用設計好的Action可以創建菜單項和工具按鈕.
Qt Designer界面下方有一個Action編輯器,可以在這個編輯器里可視化設計Action.
在Action編輯器中,編輯Action的對話框,包括以下一些設置內容:
- Text:Action的顯示文字
- Object name:Action的對象名稱
- ToolTip:當鼠標光標停留時的提示
- Icon:Action的圖標
- Checkable:Action是否可被復選
- ShortCut:Action的快捷鍵.
在Action編輯器中創建一個Action后,屬性編輯器就會顯示這幾個Action的屬性.一些屬性說明如下:
- text:用Action創建菜單項時顯示的文字.
- iconText:這是用Action創建工具按鈕時按鈕上顯示的文字.
- statusTip:這是鼠標移到Action上時的提示.
- shortcutContext:這是Action快捷鍵的有效響應范圍.
- autoRepeat:當快捷鍵一直按下時,Action是否自動重復執行.
- menuRole:在macOS上才有作用的功能.
- iconVisibleInMenu:表示菜單項上是否需顯示Action圖標.
- shortcutVisuableInContextMenu:表示使用Action創建右鍵快捷菜單時,是否顯示快捷鍵.
- priority:表示Action在UI上的優先級.


工具欄對應QToolBar類,選擇一個工具欄后,在屬性編輯器中可對其屬性進行設置.
| 屬性名稱 | 屬性值類型 | 含義與作用 |
|---|---|---|
| movable | bool | 工具欄是否可移動 |
| allowedAreas | Qt::ToolBarAreas | 工具欄可以放置的窗口區域 |
| orientation | Qt::Orientation | 工具欄的方向 |
| iconSize | QSize | 圖標的大小 |
| toolButtonStyle | Qt::ToolButtonStyle | 工具按鈕樣式 |
| floatable | bool | 工具欄是否可浮動 |
屬性toolButtonStyle的取值決定了工具按鈕顯示的樣式,屬性值Qt::ToolButtonStyle有以下幾種枚舉值.
- Qt::ToolButtonIconOnly:只顯示圖標
- Qt::ToolButtonTextOnly:只顯示文字
- Qt::ToolButtonTextBesideIcon:文字顯示在圖標旁邊
- Qt::ToolButtonTextUnderIcon:文字顯示在圖標下面
- Qt::ToolButtonFollowStyle:由QStyle樣式定義
QAction的類大部分接口函數是用于屬性讀寫的函數.
QAction還定義了一些信號和公有槽.QAction主要的信號有:
- void changed()//Action的text等屬性發生改變時
- void checkableChanged(bool checkable)//checkable的屬性變化時
- void enabledChanged(bool enabled)//enabled屬性值變化時
- void hovered()//鼠標移動至該Action上時
- void toggled(bool checked)//checked屬性值變化時
- void triggered(bool checked=false)//點擊此Action時
- void visibleChanged()//visible屬性值變化時
當我們點擊Action創建的菜單項/工具按鈕或按下Action的快捷鍵時,QAction屬性發射triggered()信號.
當Action的checked屬性變化時,Action會發射toggled(bool)信號.
QAction定義了一些公有槽,這些公有槽可以在程序中直接調用或connect.
- void hover()//觸發hovered()信號
- void trigger()//觸發triggered()信號
- void resetEnabled()//復位enabled為默認值
- void setChecked(bool)//設置checked屬性的值
- void setDisabled(bool b)//設置enabled屬性的值
- void setVisible(bool)//設置visible屬性的值
- void toggle()//反轉checked屬性的值
在UI可視化設計時,可以用Action可視化地創建工具欄上的按鈕,但是不能可視化地在工具欄上放置其他組件.
QToolBar提供了接口函數,可以通過代碼在工具欄上添加組件,從而靈活地設計工具欄.
- void addAction(QAction *action)//添加一個Action
- QAction *addWidget(QWidget *widget)//添加一個界面組件
- QAction *insertWidget(QAction *before,QWidget *widget)//插入一個界面組件
- QAction *addSeparator()//添加一個分隔條
- QAction *insertSeparator(QAction *before)//插入一個分隔條
主窗口上的狀態欄對應的是QStatusBar類,在UI可視化設計時,不能在狀態欄上放置任何組件,而只能通過其接口函數向狀態欄添加組件.
QStatusBar有兩個函數用于添加組件,其原型如下:
- void addWidget(QWidget *widget,int stretch=0)//添加正常組件
- void addPermanentWidget(QWidget *widget,int strech=0)//添加永久組件
QStatusBar類有兩個公有槽,可以顯示和清楚臨時消息,定義如下:
- void showMessage(const QString &message,int timeout=0)//顯示臨時消息
- void clearMessage()//清除臨時消息
如果一個Action的statusTip屬性不為空,當鼠標移到這個Action創建的菜單或按鈕上時,狀態欄就會自動顯示這個Action的statusTip屬性的內容:當鼠標移出時,臨時消息就會被自動清除.
下面是一個使用QAction,QToolBar,QStatusBar的綜合例子:
mainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QActionGroup>
#include <QLabel>
#include <QFontComboBox>
#include <QSpinBox>
#include <QProgressBar>
#include <QTextCharFormat>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
QLabel* lbFile;
QProgressBar* progressBar;
QSpinBox* spinFontSize;
QLabel* lbFontSize;
QFontComboBox* fcomFont;
private slots:
void on_actNewFile_triggered();
void on_actOpenFile_triggered();
void on_actSaveFile_triggered();
void on_pltEdit_copyAvailable(bool b);
void on_pltEdit_selectionChanged();
void on_actBlod_triggered(bool checked);
void on_actItalian_triggered(bool checked);
void on_actUnderline_triggered(bool checked);
void on_spinFontSize(int fontSize);
void on_fcomCombo(QFont font);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//中英界面互斥
ui->setupUi(this);
QActionGroup *acgLanguage = new QActionGroup(this);
acgLanguage->addAction(ui->actChinese);
acgLanguage->addAction(ui->actEnglish);
acgLanguage->setExclusive(true);
//創建一些無法通過GUI界面設計的組件
spinFontSize=new QSpinBox(this);
spinFontSize->setMinimum(5);
spinFontSize->setMaximum(50);
spinFontSize->setValue(ui->pltEdit->font().pointSize());
spinFontSize->setMinimumWidth(50);
QLabel* lbSpinFont= new QLabel(QString("字號"),this);
QLabel* lbFontComboBoxFont= new QLabel(QString("字體"),this);
fcomFont= new QFontComboBox(this);
fcomFont->setMaximumWidth(80);
fcomFont->setFont(ui->pltEdit->font());
ui->toolBar->addWidget(lbSpinFont);
ui->toolBar->addWidget(spinFontSize);
ui->toolBar->addWidget(lbFontComboBoxFont);
ui->toolBar->addWidget(fcomFont);
ui->toolBar->addSeparator();
ui->toolBar->addAction(ui->actClose);
ui->toolBar->addSeparator();
//狀態欄相關
lbFile= new QLabel(this);
lbFile->setMaximumWidth(150);
lbFile->setText(QString("文件名:"));
ui->statusbar->addWidget(lbFile);
progressBar= new QProgressBar(this);
progressBar->setMinimum(5);
progressBar->setMaximum(50);
progressBar->setValue(ui->pltEdit->font().pointSize());
ui->statusbar->addWidget(progressBar);
lbFontSize= new QLabel(QString("Permanent"),this);
ui->statusbar->addPermanentWidget(lbFontSize);
//信號與槽
connect(spinFontSize,SIGNAL(valueChanged(int)),this,SLOT(on_spinFontSize(int)));
connect(fcomFont,SIGNAL(currentFontChanged(QFont)),this,SLOT(on_fcomCombo(QFont)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actNewFile_triggered()
{
ui->pltEdit->clear();
ui->pltEdit->document()->setModified(false);
lbFile->setText("文件名:新建文件");
}
void MainWindow::on_actOpenFile_triggered()
{
lbFile->setText(QString("正在打開文件"));
for(int i=1;i<99;i++){
progressBar->setValue(i);
_sleep(1);
}
lbFile->setText(QString("文件名:新建文件"));
progressBar->setValue(ui->pltEdit->font().pointSize());
}
void MainWindow::on_actSaveFile_triggered()
{
ui->pltEdit->clear();
ui->pltEdit->document()->setModified(false);
QString str= lbFile->text();
lbFile->setText("文件已保存");
_sleep(2);
lbFile->setText(str);
}
void MainWindow::on_pltEdit_copyAvailable(bool b)
{
ui->actCopy->setEnabled(b);
ui->actCut->setEnabled(b);
ui->actPaste->setEnabled(ui->pltEdit->canPaste());
}
void MainWindow::on_pltEdit_selectionChanged()
{
QTextCharFormat fmt= ui->pltEdit->currentCharFormat();
ui->actBlod->setChecked(fmt.font().bold());
ui->actItalian->setChecked(fmt.font().italic());
ui->actUnderline->setChecked(fmt.font().underline());
spinFontSize->setValue(fmt.font().pointSize());
fcomFont->setCurrentFont(fmt.font());
}
void MainWindow::on_actBlod_triggered(bool checked)
{
QTextCharFormat fmt= ui->pltEdit->currentCharFormat();
if(checked)
fmt.setFontWeight(QFont::Bold);
else
fmt.setFontWeight(QFont::Normal);
ui->pltEdit->setCurrentCharFormat(fmt);
}
void MainWindow::on_actItalian_triggered(bool checked)
{
QTextCharFormat fmt= ui->pltEdit->currentCharFormat();
fmt.setFontItalic(checked);
ui->pltEdit->setCurrentCharFormat(fmt);
}
void MainWindow::on_actUnderline_triggered(bool checked)
{
QTextCharFormat fmt= ui->pltEdit->currentCharFormat();
fmt.setFontUnderline(checked);
ui->pltEdit->setCurrentCharFormat(fmt);
}
void MainWindow::on_spinFontSize(int fontSize)
{
QTextCharFormat fmt=ui->pltEdit->currentCharFormat();
fmt.setFontPointSize(fontSize);
progressBar->setValue(fontSize);
ui->pltEdit->setCurrentCharFormat(fmt);
}
void MainWindow::on_fcomCombo(QFont font)
{
QTextCharFormat fmt=ui->pltEdit->currentCharFormat();
fmt.setFont(font);
ui->pltEdit->setCurrentCharFormat(fmt);
lbFontSize->setText(QString("字體:%1").arg(font.family()));
}
在此還需要補充QPlainTextEdit相關的一些使用.
QPlainTextEdit組件定義了許多用于編輯操作的槽函數,其也有一些信號函數:
- void blockCountChanged(int newBlockCount)//段落數變化時
- void copyAvailable(bool yes)//有文字被選擇或取消選擇時
- void cursorPositionChanged(bool changed)//光標位置變化時
- void modificationChanged(bool changed)//文檔的修改狀態變化時
- void redoAvailable(bool available)//redo操作狀態變化時
- void selectionChanged()//選擇的內容變化時
- void textChanged()//文檔內容變化時
- void undoAvailable(bool available)//undo操作狀態變化時
- void updateRequest(const QRect &rect,int dy)//需要更新顯示時
QToolButton和QListWidget
Qt中用于處理項數據(item data)的組件有兩類:
一類是Item Views組件,包括QListView,QTreeView,QTableView等;
另一類是Item Widgets組件,包括QListWidget,QTreeWidget,QTableWidget等.
Item Widgets組件直接將數據存儲在每一個項里,一個項存儲了文字,文字的格式定義,圖標,用戶數據等內容.
QToolBox是工具箱組件類,工具箱是一種垂直分頁的多頁容器組件.在UI可視化設計時,在工具箱組件上點擊鼠標右鍵調出快捷菜單,可以分別使用Insert Page和Delete Page菜單項添加和刪除頁面.
工具箱的每一個頁面都是一個QWidget組件,在頁面的工作區可以放置任何其他界面組件.
QToolBox有一個信號,其中index是當前頁面序號:
- void QToolBox::currentChanged(int index)
對于QListWidget,其有的QListWidgetItem有一個標識變量flags,用于設置列表項的特性.
flags是枚舉類型Qt::ItemFlag的枚舉值的組合:
- Selectable:列表項可被選擇,Qt::ItemIsSelectable
- Editable:列表項可被編輯,Qt::ItemIsEditable
- DragEnabled:列表項可以被拖動,Qt::ItemIsDragEnabled
- DropEnabled:列表項可以接收拖放的項,Qt::ItemIsDropEnabled
- UserCheckable:列表項可以被復選,Qt::ItemIsUserCheckable
- Enabled:列表項可用,Qt::ItemIsEnabled
- Tristate:自動改變列表項復選狀態,Qt::ItemIsAutoTristate
QToolButton繼承于一般的QAbstractButton,并在此基礎上有新增的屬性:
- popupMode屬性:屬性值為QToolButton::ToolButtonPopupMode.這個屬性決定了彈出菜單的模式.
- QToolButton::DelayedPopup:按鈕上沒有任何附加的顯示內容.如果按鈕有下拉菜單,則按下按鈕并延時一會兒后才顯示下拉菜單.
- QToolButton::MenuButtonPopup:會在按鈕右側顯示一個帶箭頭的下拉按鈕.
- QToolButton::InstantPopup:會在按鈕右下角顯示一個很小的下拉箭頭圖標.
- toolButtonStyle屬性:屬性值是枚舉類型Qt::ToolButtonTextBesideIcon.比歐仕工具按鈕上文字標的顯式方式.
- autoRaise屬性:如果設置為true,按鈕就沒有邊框,鼠標移動到按鈕上才顯示邊框.
- arrowType屬性:屬性值是枚舉類型Qt::ArrowType,默認值Qt::NoArrow.不會在上面顯示內容.
除了與讀寫相關的一些接口函數,QToolButton類還有兩個主要的函數:
- setDefaultAction()函數:這個函數用于為工具按鈕設置關聯的Action
- void QToolButton::setDefaultAction(QAction*action)
- setMenu()函數:這個函數用于為工具按鈕設置下拉菜單,其函數原型定義如下:
- void QToolButton::setMenu(QMenu*menu)
QMenu是菜單類,它直接從QWidget繼承而來.在Qt Designer中我們可以通過Action窗口創建菜單欄.
QMenu是管理菜單的類,它的父類是QWidget,菜單實際上是一種窗口.創建菜單主要會用到一下幾個函數:
- void QWidget::addAction(QAction*action)//添加Action
- QAction *QMenu::addMenu(QMenu *menu)//添加菜單
- QAciton *QMenu::addSeparator()//添加一個分隔條
顯示菜單可以使用exec()函數,其函數原型定義如下:
- QAction *QMenu::exec(const QPoint&p,QAction*action=nullptr)
參數p表示菜單左上角坐標,顯示鼠標右鍵快捷菜單時,通常使用鼠標光標的當前位置QCursor::pos()作為參數p的值.
QListWidget組件的列表項是QListWidgetItem對象.QListWidgetItem沒有父類,所以沒有屬性,但是它有一些讀取函數與設置函數:
| 讀取函數 | 設置函數 | 數據類型 | 設置函數的功能 |
|---|---|---|---|
| text() | setText() | QString | 設置項的文字 |
| icon() | setIcon() | QIcon | 設置項的圖標 |
| data() | setData() | QVariant | 為項的不同角色設置數據 |
| flags() | setFlags() | Qt::ItemFlag | 設置項的特性,是Qt::ItemFlag的組合 |
| checkState() | setCheckState() | Qt::CheckState | 設置項的復選狀態 |
| isSelected() | setSelected() | bool | 設置為當前項 |
QListWidget的主要接口函數則見下:
| 分組 | 函數名 | 功能 |
|---|---|---|
| 添加或刪除項 | void addItem() | 添加一個項 |
| void addItems() | 一次添加多個項 | |
| void insertItem() | 在某一行前面插入一個項 | |
| void insertItems() | 在某一行前面一次插入多個項 | |
| QListWidgetItem *takeItem() | 從列表組件中移除一個項,并返回這個項 的對象指針,但不從內存中刪除這個項 |
|
| void clear() | 移除列表中所有的項,并從內存中刪除 | |
| 項的訪問 | QListWidgetItem *currentItem() | 返回當前項 |
| void setCurrentItem() | 設置當前項 | |
| QListWidgetItem *item() | 根據行號返回一個項 | |
| QListWidgetItem *itemAt() | 根據屏幕坐標返回項 | |
| int currentRow() | 返回當前行的行號 | |
| void setCurrentRow() | 設置當前行 | |
| int row() | 返回一個項所在行號 | |
| int count() | 返回列表組件中項的個數 | |
| 排序 | void setSortingEnabled() | 設置列表是否可排序 |
| bool isSortingEnabled() | 列表是否可排序 | |
| void sortItems() | 對列表按照指定方式排序 |
QListWidget組件中的每一行是一個QListWidgetItem對象.
QListWidgetItem的函數setFlags()用于設置項的一些特性.其函數原型定義如下:
- void QListWidgetItem::setFlags(Qt::ItemFlags flags)
QListWidget定義的信號比較多,各信號的定義如下:
- void currentItemChanged(QListWidget *current,QListWidgetItem *previous)
- void currentRowChanged(int currentRow)
- void currentTextChanged(const QString& currentText)
- void itemSelectionChanged()
- void itemChanged(QListWidgetItem *item)
- void itemActivated(QListWidgetItem *item)
- void itemEntered(QListWidgetItem *item)
- void itemPressed(QListWidgetItem *item)
- void itemClicked(QListWidget *item)
- void itemDoubleClicked(QListWidgetItem *item)
每個繼承自QWidget的類都有customContexrMenuRequested()信號,在一個組件上點擊鼠標右鍵時,組件發射這個信號,用于請求創建快捷菜單.
要是QWidget組件在點擊鼠標右鍵時發射customContextMenuRequested()信號,還需要設置contextMenuPolicy屬性:
- Qt::NoContextMenu:組件沒有快捷菜單,由其父容器組件處理
- Qt::PreventContextMenu:阻止快捷菜單,并且點擊鼠標右鍵事件也不會交給父容器組件處理.
- Qt::DefaultContextMenu:默認的快捷菜單,QWidget::contextMenuEvent()事件被自動處理.
- Qt::ActionsContextMenu:自動根據QWidget::actions()返回的Action列表創建并顯示快捷菜單.
- Qt::CustomContextMenu::組件發射customContextMenuRequested()信號,由用戶編程實現快捷菜單.
下面是一個綜合使用QToolButton和QListWidget的例子:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->actQuit,SIGNAL(triggered(bool)),this,SLOT(close()));
ui->toolButton->setDefaultAction(ui->actInitList);
ui->toolButton_2->setDefaultAction(ui->actDeleteList);
ui->toolButton_3->setDefaultAction(ui->actAddItem);
ui->toolButton_5->setDefaultAction(ui->actInsertItem);
ui->toolButton_6->setDefaultAction(ui->actDeleteItem);
ui->tbnSelAll_2->setDefaultAction(ui->actSelectAll);
ui->tbnSelNone_2->setDefaultAction(ui->actSelectNone);
ui->tbnSelInv_2->setDefaultAction(ui->actSelectInv);
QMenu* menuSelection=new QMenu(this);
menuSelection->addAction(ui->actSelectAll);
menuSelection->addAction(ui->actSelectInv);
menuSelection->addAction(ui->actSelectNone);
ui->tbnSelItems->setPopupMode(QToolButton::MenuButtonPopup);
ui->tbnSelItems->setMenu(menuSelection);
ui->tbnSelItems->setDefaultAction(ui->actSelection);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_actInitList_triggered()
{
ui->listWidget_2->clear();
QIcon icon(QString(":/img/img/redo.jpg"));
bool chk=ui->chkEditable_2->isChecked();
for(int i=0;i<10;i++){
QListWidgetItem* aItem= new QListWidgetItem();
aItem->setIcon(icon);
aItem->setText(QString("Item %1").arg(i));
aItem->setCheckState(Qt::Checked);
if(chk)
aItem->setFlags(Qt::ItemIsEditable|Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
else
aItem->setFlags(Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt::ItemIsEnabled);
ui->listWidget_2->addItem(aItem);
}
}
void MainWindow::on_actDeleteList_triggered()
{
ui->listWidget_2->clear();
}
void MainWindow::on_actAddItem_triggered()
{
QIcon icon(QString(":/img/img/redo.jpg"));
bool chk=ui->chkEditable_2->isChecked();
QListWidgetItem* aItem= new QListWidgetItem();
aItem->setIcon(icon);
aItem->setText(QString("New Item"));
aItem->setCheckState(Qt::Checked);
if(chk)
aItem->setFlags(Qt::ItemIsEditable|Qt::ItemIsSelectable|Qt::ItemIsUserCheckable|Qt:
主站蜘蛛池模板:
国产精品女生自拍第一区|
新安县|
中文字幕av无码免费一区|
成人精品一区二区三区四|
亚洲国产成人av毛片大全
|
国产不卡av一区二区|
扒开双腿猛进入喷水高潮叫声|
亚洲精品不卡av在线播放|
一区二区三区四区精品视频|
免费无码AV一区二区波多野结衣|
亚洲中文字幕第二十三页|
天堂影院一区二区三区四区|
丝袜高潮流白浆潮喷在线播放|
国产精品制服丝袜白丝|
国内精品伊人久久久久影院对白|
国产精品中文字幕观看|
亚洲精品入口一区二区乱|
青青青青国产免费线在线观看
|
中文字幕国产精品专区|
亚洲日本va午夜中文字幕久久|
国产乱子伦一区二区三区视频播放|
国产高清精品在线一区二区
|
亚洲欧洲美洲在线观看|
国产一区二区三区麻豆视频|
亚洲www永久成人网站|
亚洲AV国产福利精品在现观看|
国产999精品2卡3卡4卡|
国内自拍第一区二区三区|
国产初高中生在线视频|
精品一卡2卡三卡4卡乱码精品视频|
国产精品伦人一久二久三久|
国产成人AV男人的天堂|
亚洲精品三区四区成人少|
国产午夜精品福利91|
中文字幕乱码在线播放|
国产精品自偷一区在线观看
|
久久综合色最新久久综合色
|
苍井空毛片精品久久久|
精品久久久久久无码人妻蜜桃
|
噜噜噜噜私人影院|
国产超碰无码最新上传|
