Qt6.0開發 第三章 Qt框架功能概述
第三章 Qt框架功能概述
Qt全局定義
頭文件<QtGlobal>包含一系列Qt框架中的全局定義.包括基本數據類型,函數與宏.
函數
qt中常用的函數包括:
| 函數原型 | 功能 |
|---|---|
| T qAbs(const T&value) | 返回變量value的絕對值 |
| const T& qBound(const T& min, const T& value, const T& max) |
返回value限制在min~max的值 |
| T qExchange(T& obj,U&& newValue) | 將obj的值通過newValue替換 |
| bool qFuzzyCompare(double p1,double p2) | 判斷p1與p2是否近似相等 |
| bool qFuzzyIsNull(double d) | 判斷d是否近似于0 |
| double qInf() | 返回無窮大的數 |
| const T& qMax(const T& value1, const T& value2) |
返回較大值 |
| const T& qMin(const T& value1, const T& value2) |
返回較小值 |
| qint64 qRound64(double value) | 將value近似為最接近的qint64整數 |
| int qRound(double value) | 將value近似為最接近的int整數 |
其實上面那些函數大部分都可以查文檔...
宏定義
頭文件中還定義了很多宏,下面這些是較為常見的:
- QT_VERSION: 表示Qt版本,通常展開為數字形式0xMMNNPP,例如Qt6.2.3為0x060203.
- Q_BYTE_ORDER: 表示系統內存中數據的字節序.
- Q_BIG_ENDIAN: 表示大端字節序.
- Q_LITTLE_ENDIAN: 表示小端字節序.
- Q_UNUSED(name): 用于消除聲明函數中未使用的參數帶來的警告.
- qDebug(const char* msg,...): 用于調試程序時提示中間信息.
Qt元對象系統
Qt引入了元對象系統對標準C++語言進行擴展,增加了信號與槽,屬性系統,動態翻譯等特性,為GUI程序提供了方便.
Qt元對象系統的功能建立在以下三個方面:
- QObject類是所有使用元對象系統的類的基類.
- 必須在一個類的開頭部分插入部分宏Q_OBJECT,這樣該類才可使用元對象系統特性.
- MOC為每個QObject的子類提供必要的代碼來實現元對象系統的特性.
QObject
QObject類是所有使用元對象系統的類的基類,也就是說,只要一個類的父類中有QObject,它就可以使用相關特性.
QObject的特性主要有:
- 元對象(meta object): 每個QObject及其子類的實例都有一個元對象,這個元對象是自動創建的.
- 靜態變量staticMetaObject:返回該元對象.
- 函數metaObject():返回該元對象指針.
QPushButton* btn = new QPushButton();
const QMetaObject* metaPtr = btn->metaObject();
const QMetaObject* metaObj = btn->staticMetaObject;
- 類型信息: inherits()函數可以判斷對象是不是某個類的子類的實例.
- 動態翻譯: 函數tr()用于返回一個字符串的翻譯版本,用于多語言界面應用程序設計.
- 對象樹(object tree): 對象樹指的是表示對象間從屬關系的樹狀結構.
- 信號與槽: 通過在一個類的定義中插入宏Q_OBJECT,我們就可以使用Qt相關語言特性.
- 屬性系統: 在類的定義代碼中可以用宏Q_PROPERTY定義屬性.
QMetaObject
每個QObject及其子類的實例都有一個自動創建的元對象,元對象是QMetaObject類型的實例.
元對象存儲了嘞實例所屬類的各種源數據,包括信息元數據,方法元數據,屬性元數據等.
元對象實質上是對類的描述.
QMetaObject類的主要接口函數有:
- 類的信息:
- className():返回對象的類名稱
- metaType():返回原對象的元類型
- superClass():返回類的上層父類的元對象
- inherits():判斷該類是否繼承自metaObject描述的類
- newInstance():返回該類的一個實例
- 類信息元數據:
- classInfo():返回序號為index的一條類信息的元數據,類信息為類中通過Q_CLASSINFO定義的信息
- indexOfClassInfo():返回名稱為name的類信息的序號,序號可用于classInfo函數
- classInfoCount():返回這個類的類信息條數
- classInfoOffset():返回這個類的第一條類信息的序號
- 構造函數元數據:
- constructorCount():返回該類構造函數的個數
- constructor():返回該類序號為index的構造函數的元數據
- indexOfConstructor():返回一個構造函數的序號,char*包括正則化后的函數名與參數名
- 方法元數據:
- method():返回序號為index的方法的元數據
- methodCount():返回這個類的方法的個數
- methodOffset():返回這個類的第一個方法的序號
- indexOfMethod():返回名稱為method的方法的序號
- 枚舉類型元數據:
- enumerator():返回序號為index的元數據
- enumeratorCount():返回這個類的枚舉類型個數
- enumeratorOffset():返回這類的第一個枚舉類型的序號
- indexOfEnumerator():返回名稱為name的枚舉類型的序號
- 屬性元數據:
- property():返回序號為index的元數據
- propertyCount():返回這個類的屬性的個數
- propertyOffset():返回這個類的第一個屬性的序號
- indexOfProperty():返回名稱為name的屬性的序號
- 信號與槽:
- indexOfSignal():返回名稱為signal的信號的序號
- indexOfSlot():返回名稱為slot的槽函數的序號
- 靜態函數:
- checkConnectArgs():檢查信號與槽函數的參數是否兼容
- connectSlotsByName():迭代搜索object的所有子對象,連接匹配的信號與槽函數
- invokeMethod():運行QObject對象的某個方法,包括信號,槽函數或成員方法
- normalizedSignature():將方法method的名稱和參數字符串正則化.
通過上述函數名稱及功能描述,我們不難發現,QMetaObject對象的作用主要是服務于QObject對象相關信息的查詢.
運行時類型信息
RTTI(Runtime Type Identification),是"運行時類型識別"的意思.
C++引入這個機制是為了讓程序在運行時能根據基類的指針或引用來獲得該指針或引用所指的對象的實際類型.
而在Qt中,通過QObject與QMetaObject提供的接口函數,我們可以繞開C++編譯器的RTTI支持.
- QMetaObject::className(): 運行時返回類名稱字符串
QPushButton* btn = new QPushButton();
const QMetaObject* meta = btn->metaObject();
QString str = QString(meta->className());//str=="QPushButton"
- QObject::inherits(): 用于判斷一個對象是否繼承自某個類的實例
QPushButton *btn = new QPushButton();
bool result = btn->inherits("QPushButton");//true
result = btn->inherits("QObject");//true
result = btn->inherits("QWidget");//true
result = btn->inherits("QCheckBox");//false
- QMetaObject::superClass: 該函數返回該元對象所描述類的父類的元對象.
QPushButton* btn= new QPushButton();
const QMetaObject* meta= btn->metaObject();
QString str1= QString(meta->className());//"QPushButton"
const QMetaObject* metaSuper= btn->metaObject()->superClass();
QString str2= QString(metaSuper->className());//"QAbstractButton"
- qobject_cast(): 對于QObject及其子類對象,可以使用qobject_cast()進行動態類型轉換.
如果自定義類要支持函數qobject_cast()那么其需要繼承自QObject,且在類定義中插入宏Q_OBJECT.
QObject* btn= new QPushButton();
const QMetaObject* meta= btn->metaObject();
QString str1= QString(meta->className());//"QPushButton"
QPushButton* btnPush= qobject_cast<QPushButton*>(btn);
const QMetaObject* meta2= btnPush->metaObject();
QString str2= QString(meta2->className());//"QPushButton"
QCheckBox* chkBox= qobject_cast<QCheckBox*>(btn);//無法自己轉換自己
屬性系統
屬性是Qt C++基于元對象系統實現的一個擴展特性.在QObject的子類中,我們可以使用宏Q_PROPERTY定義屬性.
屬性系統的作用與成員變量十分相像.
- 添加一條屬性
Q_PROERTY(type name ...)
注意理解下面屬性的形式
(READ getFunction[WRITE setFunction]|
MEMBER memName[(READ getFunction[WRITE setFunction])])
宏Q_PROPERTY定義一個值類型為type,名稱為name的屬性.
- 屬性值函數相關:
- READ:指定一個讀取屬性值的函數,沒有MEMBER關鍵字時必須設置READ
- WRITE:指定一個設置屬性值的函數,只讀屬性不設置WRITE
- MEMBER:指定一個成員變量與屬性關聯,使之成為可讀可寫的屬性
- 其他可選:
- RESET:可選的,用于指定一個設置屬性默認值的函數
- NOTIFY:可選的,當屬性值發生變化時發射此信號
- DESIGNABLE:表示屬性是否在屬性編輯器里可見,默認true
- USER:表示用戶是否可編輯,默認為false
- CONSTANT:表示屬性是一個常數,不能與NOTIFY共存
- FINAL:表示所定義的屬性不能被子類重載
Qt屬性機制還可以在運行時添加與使用屬性,這種屬性被稱為動態屬性.
- 使用一個動態屬性
object->property("屬性名");
- 設置一個動態屬性
object->setProperty("屬性名",value);
由于Qt的元對象機制,屬性也存在對應的屬性元數據類型.
- 獲得屬性的序號
int index= metaObject->indexOfProperty("屬性名");
- 獲得屬性的元數據
QMetaProperty prop= metaObject->property(index);
元對象系統還支持使用宏Q_CLASSINFO在類中定義一些類信息,類信息有名稱和值,只能用字符串表示.
- 添加一條類信息
Q_CLASSINFO("名稱","值");
- 獲得類信息
QMetaClassInfo info= metaObject->classInfo(index)
其中,QMetaClassInfo類有name()與value()兩個成員函數.
信號與槽
信號與槽是Qt的核心機制,也是它區別于其他C++開發框架的重要特性.
信號與槽作為對象間通信機制,其也是由Qt元對象系統支持實現的.其隱藏了復雜的底層實現.
函數connect()有一種成員函數形式,還有多種靜態函數形式.一般使用靜態函數形式.
- connect()函數一般形式
connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));
這里使用了SIGNAL()與SLOT()指定信號與槽函數,如果信號與槽函數帶有參數,還需要說明參數類型.
如下所示:
connect(sender,SIGNAL(signal(int)),receiver,SLOT(slot(int)));
另一種參數形式的靜態函數QObject::connect()無需通過宏實現:
- connect()函數另一種靜態函數形式
connect(sender,&QSomeObject::signal,receiver,&QOtherObject::slot);
這樣可以用上面的語句將信號與槽關聯起來,無需出現函數參數.
如果出現具有不同參數列表的同名信號函數,那么這一形式connect()也將根據參數將其與不同槽函數對應.
但是當槽函數與信號函數都存在同名函數且不止一個參數列表匹配,那么就會出現錯誤.
UI文件經過MOC編譯轉換為C++頭文件時,在Action編輯器里設置的信號與槽的連接會在函數setupUi中自動生成.
不管是哪種參數形式的connect()函數,最后都有一個參數type,它是枚舉類型Qt::ConnectionType,默認值為Qt::AutoConnection.表示信號與槽的關聯方式,有以下幾個值:
- Qt::AutoConnection:如果信號的接收者與發送者在同一個線程中,就使用Qt::DirectConnection方式,否則使用Qt::QueuedConnection方式.
- Qt::DirectConnection:信號被發射時,槽函數立即運行,槽函數與信號函數在同一個線程中.
- Qt::QueuedConnection:在事件循環回到接收者線程后運行槽函數,槽函數與信號在不同的線程中.
- Qt::BlockingQueuedConnection:與Qt::QueuedConnection相似,區別是信號線程會阻塞,直到槽函數運行完畢.
還有一個作為QObject成員函數的connect(),其沒有表示接收者的參數,接收者就是對象自身:
- connect()的成員函數形式
this->connect(sender,SIGNAL(signal(int)),SLOT(slot(int)));
與connect()相應的,存在函數disconnect()用于解除信號與槽的連接.
- 解除與一個發射者所有信號的連接(靜態函數形式)
disconnect(sender,nullptr,nullptr,nullptr);
- 解除與一個發射者所有信號的連接(成員函數形式)
object->disconnect();
- 解除與一個特定信號的所有連接(靜態函數形式)
disconnect(sender,SIGNAL(signal()),nullptr,nullptr);
- 解除與一個特定信號的所有連接(成員函數形式)
object->disconnect(SIGNAL(signal));
- 解除與一個特定接收者的所有連接(靜態函數形式)
disconnect(sender,nullptr,receiver,nullptr);
- 解除與一個特定接收者的所有連接(成員函數形式)
object->disconnect(receiver);
- 解除特定的一個信號與槽的連接
disconnect(sender,&QSomeObject::signal,receiver,&QOtherObject::slot);
此外,Qt還在QObject中提供了一個sender()函數用于獲得發射者的QObject對象指針.
一般是在槽函數中使用sender()可以獲得發射者的QObject對象指針.
而且,在自己設計的類里,不僅可以自定義槽函數,也可以自定義信號.
信號就是在類定義里聲明的一個無返回值函數.
信號函數可以有輸入參數,其無須實現,而只需在某些條件下被發射.
下面是一個例子:
class Dialog : public QDialog
{
Q_OBJECT
//....
private slots:
//測試自定義信號
void do_reactionToSignal();
signals:
void do_checkedRadio();
};
//Dialog.h
void Dialog::do_pushButtonOk()
{
emit do_checkedRadio();
return;
}
void Dialog::do_reactionToSignal()
{
QPalette plet= txtEdit->palette();
plet.setColor(QPalette::Text,Qt::green);
txtEdit->setPalette(plet);
return;
}
Dialog::Dialog(QWidget *parent)
: QDialog(parent)
{
//...
//新建豎向布局
QVBoxLayout *VLay= new QVBoxLayout;
//按鈕
btnOk= new QPushButton("確定");
QHBoxLayout *HLay3= new QHBoxLayout;
HLay3->addWidget(btnOk);
connect(btnOk,SIGNAL(clicked()),this,SLOT(do_pushButtonOk()));
//文本欄
txtEdit= new QPlainTextEdit;
txtEdit->setPlainText("Qt6.0 學習\n第二章 項目二");
//測試自定義信號函數
connect(this,SIGNAL(do_checkedRadio()),this,SLOT(do_reactionToSignal()));
//...
}
//Dialog.cpp
在其中,信號函數do_checkedRadio只需要聲明,而不需要實現.
將其與槽函數connect()后,實際上只需對其emit便可發送信號.
這是很方便的.
對象樹
使用QObject及其子類創建的對象是以對象樹的形式來組織的.
創建一個QObject對象時若設置一個父對象,它就會被添加到父對象的子對象列表里.
一個父對象被刪除時,其全部子對象就會被自動刪除.
這種對象樹的結構對于窗口上的對象管理特別有用.
與之相關的函數主要有三個
- children():這個函數返回對象的子對象列表,為QObjectList類型,為QObject類型指針列表.
typedef Qlist<QObject*>QObjectList;
- findChild():這個函數用于在對象的子對象中查找可以轉換為類型T的子對象.
例如:我們要查找窗口上對象名稱為btnOK的QPushButton按鈕:
QPushButton *btn= this->findChild<QPushButton*>("btnOK");
- findChildren():這個函數用于在對象的子對象中查找可以轉換為類型T的子對象,且以子對象列表形式返回.
例如:
QList<QPushButton*>btnList= ui->groupBox_Btns->findChildren<QPushButton*>();
上述知識綜合應用
下面是本章的一個綜合應用:
tperson.h
#ifndef TPERSON_H
#define TPERSON_H
#include <QObject>
class TPerson : public QObject
{
Q_OBJECT
Q_CLASSINFO("author","MesonoxianY");
Q_CLASSINFO(
"note",
"you should know that is just a test."
);
Q_CLASSINFO("version","0.01beta");
Q_PROPERTY(int age MEMBER m_age);
Q_PROPERTY(int score MEMBER m_score);
Q_PROPERTY(QString name MEMBER m_name);
public:
explicit TPerson(QObject *parent = nullptr,QString name= "nobody");
~TPerson();
int getPersonAge();
QString getPersonName();
void setPersonAge(int input_age);
void increaseAge();
private:
QString m_name;
int m_age,m_score;
private slots:
signals:
void changeAgeSignal(int input_age);
};
#endif // TPERSON_H
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include "tperson.h"
#include <QWidget>
#include <QMetaProperty>
#include <QMetaClassInfo>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
TPerson *boy,*girl;
private slots:
void do_ageChange(int input_age);
void do_ageSpinChange(int change_age);
void do_btnBoy(bool checked);
void do_btnGirl(bool checked);
void do_btnClear(bool checked);
void do_btnMetaObjectInfo(bool checked);
};
#endif // WIDGET_H
tperson.cpp
#include "tperson.h"
#include <QDebug>
TPerson::TPerson(QObject *parent,QString name)
: QObject{parent},m_name(name),m_age(8),m_score(78)
{
return;
}
TPerson::~TPerson()
{
qDebug()<<"TPerson object destoryed.";
}
int TPerson::getPersonAge()
{
return this->m_age;
}
QString TPerson::getPersonName()
{
return this->m_name;
}
void TPerson::setPersonAge(int input_age)
{
this->m_age=input_age;
emit changeAgeSignal(m_age);
return;
}
void TPerson::increaseAge()
{
this->m_age++;
emit changeAgeSignal(m_age);
return;
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
ui->spinBoxBoy->setProperty("sex","male");
ui->spinBoxGirl->setProperty("sex","female");
//TPerson相關
boy= new TPerson(this,"Tom");
boy->setProperty("sex","male");
girl = new TPerson(this,"Jenny");
girl->setProperty("sex","female");
connect(boy,SIGNAL(changeAgeSignal(int)),this,SLOT(do_ageChange(int)));
connect(girl,SIGNAL(changeAgeSignal(int)),this,SLOT(do_ageChange(int)));
connect(boy,SIGNAL(changeAgeSignal(int)),ui->spinBoxBoy,SLOT(setValue(int)));
connect(girl,SIGNAL(changeAgeSignal(int)),ui->spinBoxGirl,SLOT(setValue(int)));
//輸入框相關
connect(ui->spinBoxBoy,SIGNAL(valueChanged(int)),this,SLOT(do_ageSpinChange(int)));
connect(ui->spinBoxGirl,SIGNAL(valueChanged(int)),this,SLOT(do_ageSpinChange(int)));
//按鈕相關
connect(ui->btnBoy,SIGNAL(clicked(bool)),this,SLOT(do_btnBoy(bool)));
connect(ui->btnGirl,SIGNAL(clicked(bool)),this,SLOT(do_btnGirl(bool)));
connect(ui->btnClearText,SIGNAL(clicked(bool)),this,SLOT(do_btnClear(bool)));
connect(ui->btnMetaObjectInfo,SIGNAL(clicked(bool)),this,SLOT(do_btnMetaObjectInfo(bool)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::do_ageChange(int input_age)
{
Q_UNUSED(input_age);
QString str;
TPerson *person=qobject_cast<TPerson*>(sender());
str=QString("%1,%2的年齡=%3")
.arg(person->property("name").toString())
.arg(person->property("sex").toString())
.arg(person->getPersonAge());
ui->textEdit->appendPlainText(str);
return;
}
void Widget::do_ageSpinChange(int change_age)
{
QSpinBox *spin_box=qobject_cast<QSpinBox*>(sender());
if(spin_box->property("sex")=="male")
boy->setPersonAge(change_age);
else
girl->setPersonAge(change_age);
return;
}
void Widget::do_btnBoy(bool checked)
{
boy->increaseAge();
return;
}
void Widget::do_btnGirl(bool checked)
{
girl->increaseAge();
return;
}
void Widget::do_btnClear(bool checked)
{
ui->textEdit->clear();
return;
}
void Widget::do_btnMetaObjectInfo(bool checked)
{
const QMetaObject *meta= boy->metaObject();
ui->textEdit->appendPlainText(QString("type:%1\n")
.arg(meta->className()));
ui->textEdit->appendPlainText(QString("attribution:"));
for(auto i=meta->propertyOffset();i<meta->propertyCount();i++){
auto propName=meta->property(i).name();
QString propValue=boy->property(propName).toString();
ui->textEdit->appendPlainText(QString("property name:%1\nproperty value:%2\n")
.arg(propName)
.arg(propValue));
}
ui->textEdit->appendPlainText("classinfo:");
for(auto i=meta->classInfoOffset();i<meta->classInfoCount();i++){
QMetaClassInfo classInfo=meta->classInfo(i);
ui->textEdit->appendPlainText(QString("classinfo name:%1\nclassinfo value:%2\n")
.arg(classInfo.name())
.arg(classInfo.value()));
}
return;
}
main.cpp內容為默認生成.widget.ui請自行結合理解設計.
容器類
Qt提供了多個基于模板的容器類,它們的使用方式與STL相似,且較STL而言更具優勢:
- Qt的容器類更輕巧,使用更安全且更容易使用.
- Qt容器類是隱式共享和可重入的,而且進行了速度與存儲上的優化.
- Qt容器類是線程安全的,作為只讀容器可被多個線程訪問.
Qt的容器類分為 順序容器(sequential container)類 和 關聯容器(associative container)類.
容器迭代器(iterator)用于遍歷容器內的數據項,Qt有STL類型的迭代器與Java類型的迭代器.
常用的容器
順序容器類:
- QList類:列表,對應std::list<T>的容器,但是十分靈活.
- QVector類:向量,對應std::vector<T>的容器,但是成員函數更多的按照QList習慣.
- QStack類:棧,對應std::stack<T>,是QList的子類.以pop()和push()為主.
- QQueue類:隊列,對應std::queue<T>,是QList的子類.與QStack相似.
關聯容器類: - QSet類:集合,對應于std::set<T>,是基于哈希表的集合模板類.
- QMap類:散列,對應于std::map<T>,如果不在意存儲順序,QHash會更快.
- QMultiMap類:多值映射表.
- QHash類:字典,基于哈希表實現的字典類,速度更快.
Qt中的迭代器
Qt中,每一個容器有兩個STL類型的迭代器:一個用于只讀訪問(const_iterator),一個用于讀寫訪問(iterator)
而且,在Qt中,由于使用了隱式共享,容器類作為返回值帶來的復制并不帶來太大開銷.
隱式共享(implicit sharing): 是對象的管理方法.一個對象被隱式共享,意味著只會傳遞該對象的一個指針給使用者,而不實際復制對象數據,只有在使用者修改數據時,才會實際復制共享對象給使用者.
C++中沒有自帶的foreach語句,通常通過范圍for語句與<algorithm>中的foreach()函數實現.
Qt中則加入了foreach語句,用于容器的遍歷:
- qt中使用foreach語句進行遍歷
foreach (const QType iter,list){
//body of foreach
}
其他常用的基礎類
- QVariant類:是Qt中的萬能數據類型,可以存儲任何類型的數據.
QObject::property()函數就是返回QVariant類型的值.
一個QVariant變量在任何時候只能存儲一個值,可以使用它的toT函數將其轉換為具體數據.例如toString().
對于QVariant中沒有相應toT函數的類型,可以通過value<T>模板函數轉換.
- QFlags<Enum>類
QFlags<Enum>類是一個模板類,其中Enum是枚舉類型.QFlags用于定義枚舉值或運算組合.
Qt中經常用到QFlags類:
例如:QLabel有一個alignment屬性,其屬性值為Qt::Alignment類型,其信息有如下表示:
enum Qt::AlignmentFlag//枚舉類型
flags Qt::Alignment//標志類型
那么則表示Qt::Alignment是QFlags<Qt::AlignmentFlag>類型.
Qt::AlignmentFlag是枚舉類型,其有一些枚舉常量.
Qt::Alignment是一個或多個Qt::AlignmentFlag類型枚舉值的組合,所以,我們把Qt::Alignment稱為枚舉類型Qt::AlignmentFlag的標志類型.
- QRandomGenerator類
其可以提供高質量的隨機數,在創建QRandomGenerator對象時,可以為構造函數提供一個數作為隨機數種子.
QRandomGenerator中有一個靜態函數QRandomGenerator::securelySeeded()可以創建一個隨機數發生器.
這個函數使用QRandomGenerator::system()表示的系統隨機數發生器生成的隨機數為種子.
QRandomGenerator有兩個靜態函數會返回隨機數發生器,可以直接使用而不初始化:
- QRandomGenerator *QRandomGenerator::system()
- QRandomGenerator *QRandomGenerator::global()
system代表系統隨機數發生器,global代表全局隨機數發生器.
一般直接調用即可,如下所示:
quint32 rand= QRandomGenerator::global()->generate();
QRandomGenerator生成隨機數的基本函數主要有:
- quint32 QRandomGenerator::generate()
- quint64 QRandomGenerator::generate64()
- double QRandomGenerator::generateDouble()//區間[0,1)
QRandomGenerator還支持括號運算符,如:
QRandomGenerator rand(QDateTime::currentSecsSinceEpoch());
rand()//生成隨機數
其中rand()等同于rand.generate().
而QRandomGenerator::bounded可以生成指定范圍內的隨機數,其有很多參數類型.

浙公網安備 33010602011771號