1. 程式人生 > >關於QT的系統總結(非常全面)

關於QT的系統總結(非常全面)

編譯環境與開發流程

開發QT有兩種IDE可以使用,一種是使用 VS + Qt 的外掛,另一種就是使用QtCreator工具。前一種是微軟的工具,用的都比較多容易上手,缺點是訊號槽的支援不太好,需要手寫,不能自動生成,另外可能有中文編碼的問題。後一種是Qt的官方IDE,智慧提示與除錯功能不如VS強大,但是是跨平臺的IDE,其QtDesigner設計UI介面操作比較方便,並且由於是QT官方的IDE,對編碼等支援都比較好,裡面集成了Qt的幫助文件。不得不說Qt的幫助文件做的是非常好的,整合進QtCreator環境之後更加方便。

我開發的時候使用的是QtCreator開發,目前除了除錯功能比VS差以外,其他的用的比較順手,QtCreator是跨平臺的,ubuntu上也是可以使用,開啟之後介面如下:
11

下面將對QtCreator的介面各個功能進行大致的介紹:1

我們建立一個示例專案,選擇“檔案”—“新建檔案或專案”—“應用程式”—“QT Widgets Application”選擇之後都選擇預設設定,根據提示,就得到了一個專案,我們的UI是一個基於QMainWindow的類,預設提供選單欄,狀態列。如果不需要這些,可以建立一個基於QWidget的UI類,專案如圖所示:
1

回到頂部

QT專案的構成及原理

將專案切換到編輯模式,如下:
1

這個專案中一共有4個檔案,入口檔案main.cpp、mainwindow.ui檔案、mainwindow.h和mainwindow.cpp後臺原始檔,在main函式中直接呼叫MainWindow類的show()方法顯示主介面,那麼我們切換到UI的設計檢視(雙擊專案中的mainwindow.ui檔案),在主介面上新增兩個控制元件:

1

我們看一下MainWindow.cpp的程式碼裡面應該如何操作介面上的控制元件:
1

我們使用的是ui->txtName->text();這樣的語句,也就是說並不是像在C#中一樣在後臺程式碼中直接可以通過類似this->txtName->text()的語句去訪問介面上的控制元件物件,而MainWindow類中有一個成員變數是ui,其型別是Ui::MainWindow,通過這個ui成員去訪問介面上的元素,那麼這些介面控制元件是如何初始化的呢? 我們需要檢視ui成員變數的型別Ui::MainWindow的實現,注意Ui::Mainwindow類與MainWindow類是不同的兩個類,Ui::MainWindow

類是在名稱空間Ui下的類,而MainWindow是沒有名稱空間的,我們在mainwindow.h中可以看到:

1

MainWindow中的私有成員變數ui實際上是Ui::MainWindow型別的指標,那麼Ui::MainWindow是如何定義的呢? 用滑鼠點進去就看到了:

1

從這裡就可以看出為什麼我們的MainWindow類的建構函式中一進來就呼叫ui->setupUi(this)去初始化介面了

回到頂部

QT中的佈局

QT中有四種佈局方式,分別是:Vertical垂直佈局、Horizontal水平佈局、Grid佈局、Form佈局,效果如下:

1

其實Grid佈局感覺跟HTML中的Table差不多,Form佈局好像也是表格的效果,至於這兩種佈局的差異在哪裡我也不是很清楚,專案中基本沒有用過這兩種佈局方式,一般而言所有的效果都可以通過水平佈局和垂直佈局巢狀實現。結合水平佈局和垂直佈局,以及他們之間的相互巢狀,再結合使用自動伸縮調節的佔位控制元件HorizontalSpacer和VerticalSpacer就可以實現非常複雜的佈局效果。

一般使用佈局有兩種方式,第一種即拖放這些佈局控制元件到UI介面上,然後將希望佈局的子控制元件拖放到這些佈局控制元件中,但是這種方式個人認為不夠靈活,特別是在控制元件之間希望巢狀的時候,工具箱中的佈局控制元件如下:

1

另外一種使用方式,QT的容器控制元件(那些能夠放子控制元件的控制元件)都可以為其指定一種佈局方式,當為一個容器控制元件指定佈局方式之後,該容器控制元件就會以這種佈局方式來約束其所有子控制元件,直接在Qt設計器的容器控制元件中右鍵就可以設定:

1

我們在一個QFrame控制元件中放入兩個子控制元件,一個文字框一個按鈕,之後在QFrame的空白處右鍵單擊,在其右鍵選單“佈局”的子選單中就可以指定該控制元件的佈局模式了。實際上在程式碼上的原理是一樣的,我們在QtCreator生成的ui_mainwindow.h中可以看到關於frame以及子控制元件和其佈局設定的程式碼:

1

可以看到是這麼樣的關係,QFrame的子控制元件QPushButton以及QLineEdit(文字框)在構造的時候指定的父物件就是frame,而佈局物件QHBoxLayout指定的父控制元件物件也是frame,也就是說除了我們在介面上看到的按鈕,文字框是frame的子控制元件以外,我們通過右鍵生成的佈局物件(QtCreator自動生成的,其物件id也是自動生成的),也是frame的子控制元件,QHBoxLayout通過addWidget函式將frame的所有直接子控制元件新增到佈局中進行佈局。而我們在工具箱中拖動佈局控制元件到頂級視窗UI介面之後,實際上QtCreator自動生成了一個QWidget作為該佈局控制元件的容器,並且自動生成的這個QWidget的父控制元件就是頂級的MainWindow視窗。也就是說我們每往UI介面上拖放一個佈局控制元件,那麼QtCreator會為該佈局控制元件自動生成一個QWidget作為該佈局控制元件的容器(也就是父控制元件),並且該自動生成的QWidget的父控制元件就是佈局控制元件被拖動到的位置所在的直接容器。例如:

1

當選定一個佈局控制元件(如果該佈局控制元件是從工具箱拖放到UI上的,則其在UI設計器上是可以看到的),或者是選擇一個容器控制元件的時候(如果該容器控制元件已經通過右鍵的方式指定了佈局方式)。這兩種情況下在QtCreator的屬性欄上就可以看到佈局的相關屬性:

1

如果是從工具箱中拖放的佈局控制元件,那麼其屬性中的Margin預設都是0 ,如果是通過右鍵為容器控制元件指定的佈局,那麼該佈局的Margin預設是9,所以這種方式下可以看到如果此時相容器控制元件中新增子控制元件,那麼子控制元件與容器控制元件之間是有間隙的,除非將這裡的屬性手工改為0,layoutSpacing引數對於這兩種方式產生的佈局預設值都是6,表示該佈局中的子控制元件之間的間隔是6

回到頂部

QT中的通用控制元件

QT中最常用的控制元件QPushButton(按鈕)、QLineEdit(文字框)、QRadioButton(單選框)、QCheckBox(複選框)、QFrame(一般用作容器控制元件,配合佈局)、QProgressBar(進度條控制元件)這些控制元件的使用方法都非常簡單,查一下幫助文件就可以搞定,下面的章節中,我們會講解另外的一些控制元件的常用但是卻不是很容易找到的功能。

回到頂部

QVariant 型別

再講解其他控制元件之前,我們需要先了解Qt中的QVariant型別,為什麼呢,因為需要為控制元件繫結資料,就離不開對QVariant型別的瞭解,下面章節中我們要說到的一些控制元件,在繫結資料的時候就會使用QVariant型別。他除了可以包裹Qt中常見的QString,int等型別之外,還可以包裹自定義的類物件。該型別提供了一系列的建構函式以及轉換函式來攜帶常見型別的資料,和轉換到常見型別資料的方法:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 QVariant(int val) QVariant(uint val) QVariant(qlonglong val) QVariant(qulonglong val) QVariant(bool val) QVariant(double val) QVariant(float val) QVariant(const char * val) QVariant(const QString & val) QVariant(const QDate & val) QVariant(const QTime & val) QVariant(const QDateTime & val) bool    toBool() const QByteArray  toByteArray() const QChar   toChar() const QDate   toDate() const QDateTime   toDateTime() const double  toDouble(bool * ok = 0) const float   toFloat(bool * ok = 0) const int toInt(bool * ok = 0) const QJsonArray  toJsonArray() const qlonglong   toLongLong(bool * ok = 0) const QString toString() const QTime   toTime() const uint    toUInt(bool * ok = 0) const qulonglong  toULongLong(bool * ok = 0) const

這只是其中的一部分,其實還包括了一些畫圖相關的型別的封裝,例如QPoint,QRect等,當然Qt提供的是使用頻率很高的常見的型別,有時候我們需要繫結自己定義的類物件,例如實體類:

1 2 3 4 5 6 //設定 MyClass myclass; QVariant courseModelVariant=QVariant::fromValue(myclass); //獲取 myclass = courseModelVariant.value<MyClass>();

這樣我們就可以使用QVariant攜帶任意資料型別了

回到頂部

QComboBox控制元件

下拉列表框控制元件最常見的功能需求就是為該控制元件新增下拉專案,並且為每個下拉專案新增對應的自定義隱藏資料,例如在下拉列表中每一項上面顯示的文字描述是給使用者看的,然而在程式中,我們可能需要該專案對應的隱藏資料,例如ID甚至是自定義的物件。

QComboBox類使用QComboBox::addItem(const QString &atext, const QVariant &auserData)成員函式為下拉列表新增專案,第一個引數text表示顯示在下拉項中的文字,而第二個引數我們可以利用來為該項繫結自定義的資料,其型別為QVariant型別。我們可以通過QVariant型別方便的為該下拉項關聯任意自定義的資料型別。

在獲取資料的時候,通過QComboBox:: currentData(int role = Qt::UserRole)函式獲取當前選中下拉項關聯的QVariant型別的資料,也可以通過QComboBox:: itemData(int index, int role = Qt::UserRole)獲取指定下拉項的關聯資料。通過currentText()、itemText(int index)可以獲取下拉項上顯示的文字。

回到頂部

QTableWidget控制元件

QTableWidget是Qt中的表格顯示控制元件,與C#中的Grid、GridView類似,主要是用來繫結資料。在UI設計介面中選中該控制元件之後可以在屬性欄對控制元件的屬性進行設定,最常用的屬性有如下:

focusPolicy 焦點策略,如果設定為NoFocus可以去掉單擊時候現實的單元格的虛線框
contextMenuPolicy 可以設定右鍵選單
frameShape 設定外邊框,一般設定為NoFrame去掉邊框
editTriggers觸發單元格的編輯狀態,值NoEditTriggers表示不觸發編輯狀態
selectionMode選擇模式,值ExtendedSelection表示多選
selectionBehavior選擇行為,值SelectRows按行選擇
showGrid是否顯示網格線
rowCount行數
columnCount列數
horizontalHeaderVisible是否顯示水平表頭
verticalHeaderVIsible是否顯示垂直表頭
verticalScrollBarPolicy設定垂直滾動條策略
horizontalScrollBarPolicy設定水平滾動條策略

另外的一些比較實用的功能程式碼:
在單元格中新增控制元件:

1 2 3 4 QComboBox *comBox = new QComboBox(); comBox->addItem("F"); comBox->addItem("M"); ui->qtablewidget->setCellWidget(0,3,comBox);//這裡不是setItem而是setCellWidget

為單元格新增checkBox:

1 2 3 4 5 6 QTableWidgetItem *item = new QTableWidgetItem(); //設定item的check狀態的時候,item會自動變成QCheckBox的樣子, //不必通過setCellWidget專門插入QCheckBox控制元件 //通過item->checkState()可以獲取該item是否勾選 item->setCheckState(Qt::Unchecked); ui->tableWidgetCourseList->setItem(rowIndex, columnIndex, item);

單元格中顯示字串:

1 2 QTableWidgetItem *item = new QTableWidgetItem(QString("xx")); ui->tableWidgetCourseList->setItem(rowIndex, columnIndex, item);

設定單元格關聯的自定義資料:

1 2 3 4 QTableWidgetItem *item = new QTableWidgetItem(QString("")); QVariant courseModelVariant=QVariant::fromValue(MyClass("xx")); item->setData(USER_DEFINE_ROLE,courseModelVariant); this->ui->tableWidgetCourseList->setItem(rowIndex, columnIndex, item);

獲取單元格關聯的自定義資料:

1 2 QTableWidgetItem * item = this->ui->tableWidgetCourseList->item(row,col); Myclass model = item->data(USER_DEFINE_ROLE).value<MyClass>();

設定單元格中的文字對齊方式:

1 ui->tableWidgetCourseList->item(rowIndex, columnIndex)->setTextAlignment(Qt::AlignCenter);

通過x,y座標獲取所在的item物件:

1 2 3 4 QModelIndex index = ui->tableWidgetCourseList->indexAt(QPoint(x,y)); int row = index.row(); int col = index.column(); QTableWidgetItem * item = ui->tableWidgetCourseList->item(row,col);

設定表頭的列寬:

1 ui->tableWidgetCourseList->horizontalHeader()->resizeSection(colIndex,20);//寬20

設定列寬自適應:

1 ui->tableWidgetCourseList->horizontalHeader()->setSectionResizeMode(colIndex,QHeaderView::Stretch);

初始化表頭文字:

1 2 3 4 5 QStringList headerText; headerText.append("列1"); headerText.append("列2"); headerText.append("列3"); ui->tableWidgetCourseList->setHorizontalHeaderLabels(headerText);

為表頭新增複選框按鈕:

在表頭上新增複選框不能通過在表頭單元格中新增QCheckBox的方式實現,必須進行重繪,下面的程式碼是我們自定義的表頭類
myqheaderview.h的內容:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 //該類實現自定義的表頭,主要是為了在表頭中加入CheckBox控制元件 class MyQHeaderView : public QHeaderView { Q_OBJECT public: explicit MyQHeaderView(Qt::Orientation orientation, QWidget *parent = 0); void setChecked(bool checked); signals: void headCheckBoxToggled(bool checked); protected: void paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const; void mousePressEvent(QMouseEvent *event); private: QRect checkBoxRect(const QRect &sourceRect) const; bool m_isOn; };

myqheadview.cpp的內容:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 MyQHeaderView::MyQHeaderView(Qt::Orientation orientation, QWidget *parent) : QHeaderView(orientation, parent) , m_isOn(false) { // set clickable by default setChecked(false); } void MyQHeaderView::setChecked(bool checked) { if (isEnabled() && m_isOn != checked) { m_isOn = checked; updateSection(0); emit headCheckBoxToggled(m_isOn); } } void MyQHeaderView::paintSection(QPainter *painter, const QRect &rect, int logicalIndex) const { painter->save(); QHeaderView::paintSection(painter, rect, logicalIndex); painter->restore(); if (logicalIndex == 0) { QStyleOptionButton option; if (isEnabled()) option.state |= QStyle::State_Enabled; option.rect = checkBoxRect(rect); if (m_isOn) option.state |= QStyle::State_On; else option.state |= QStyle::State_Off; style()->drawControl(QStyle::CE_CheckBox, &option, painter); } } void MyQHeaderView::mousePressEvent(QMouseEvent *event) { if (isEnabled() && logicalIndexAt(event->pos()) == 0) { m_isOn = !m_isOn; updateSection(0); emit headCheckBoxToggled(m_isOn); } else QHeaderView::mousePressEvent(event); } QRect MyQHeaderView::checkBoxRect(const QRect &sourceRect) const { QStyleOptionButton checkBoxStyleOption; QRect checkBoxRect = style()->subElementRect(QStyle::SE_CheckBoxIndicator, &checkBoxStyleOption); QPoint checkBoxPoint(sourceRect.x()+5, sourceRect.y() + sourceRect.height() / 2 - checkBoxRect.height() / 2); return QRect(checkBoxPoint, checkBoxRect.size()); }

使用自定義表頭:

1 2 MyQHeaderView*myHeader=new MyQHeaderView(Qt::Horizontal, ui->tableWidgetCourseList); ui->tableWidgetCourseList->setHorizontalHeader(myHeader);

為QTableWidget新增一行資料實際上是根據行數和列數,迴圈QTableWidget的所有單元格,對每個單元格item設定資料來實現的。

回到頂部

QTabWidget控制元件

該控制元件類就是一個選項卡控制元件,有多個tab頁,下面是一些實用的方法:

切換到tab:

1 ui->tabWidgetExportEdit->setCurrentIndex(tabIndex);

移除選項卡:

1 ui->tabWidgetExportEdit->removeTab(tabIndex);

關於選項卡控制元件的操作不多,重要的是怎麼美化控制元件的顯示,QSS將會作為單獨的一篇文章來講解如何美化Qt中的各種控制元件。

回到頂部

QWebview控制元件

該控制元件是用於在Qt中顯示網頁的控制元件,一般而言會將contextMenuPolicy屬性設定為NoContextMenu隱藏系統為其提供的預設右鍵選單

<1>. 載入網頁:

1 2 3 ui->webViewCut->load(QUrl()); //如果是本地網頁,必須使用file:///的字首作為網頁地址 ui->webViewCut->load(QUrl());

<2>. Qt程式碼中呼叫QWebview載入的網頁中的js函式:

1 2 3 4 5 6 7 8 9 10 //先作如下設定 ui->webViewCut->page()->setForwardUnsupportedContent(true); ui->webViewCut->page()->settings()->setAttribute(QWebSettings::JavascriptEnabled, true); ui->webViewCut->page()->settings()->setAttribute(QWebSettings::PluginsEnabled, true); ui->webViewCut->page()->settings()->setAttribute(QWebSettings::JavaEnabled, true); ui->webViewCut->page()->settings()->setAttribute(QWebSettings::AutoLoadImages, true); //然後在QWebview的loadFinished槽函式中呼叫js,該槽函式表示網頁已經載入完畢 QString js = QString("alert(\'hello Qt!\')"); ui->webViewCut->page()->mainFrame()->evaluateJavaScript(js);

<3>. 在QWebview載入的html的js程式碼中呼叫Qt的函式:

預設情況下在QwebViewCut中的網頁裡面的js不能直接呼叫Qt中的相關功能,這涉及到安全性問題。要滿足js中呼叫Qt的功能必須滿足下面的條件:

在Qt中暴露一個物件給js,然後js就可以在網頁中直接使用這個物件以及該物件的[特定]函式,要求是被暴露Qt物件必須繼承自QObject類,並且在js中呼叫這個暴露的物件的成員函式的定義是有要求的,該物件的滿足下面的要求的成員函式都可以直接被js呼叫:

1.必須是該物件的公共函式,並且在函式宣告前面新增Q_INVOKABLE修飾,例如:

1 2 public : Q_INVOKABLE int TestQt();

2.如果該函式被宣告成一個public slot 也可以不新增Q_INVOKABLE修飾:

1 2 public slots: void TestQt();

個人認為第一種方法更好,因為可以設定返回值,而Qt的槽函式是沒有返回值的,都是返回void,只需要呼叫this->ui->webViewCut->page()->mainFrame()->addToJavaScriptWindowObject("QtObj", this); 就可以將一個Qt物件,也就是這裡傳遞的this代表的物件,當然也可以直接傳遞其他物件指標,暴露給網頁中的javascript,網頁中的javascript在呼叫的時候可以直接使用 QtObj 去引用我們的Qt物件,以及通過QtObj去直接呼叫符合條件的Qt物件的成員函式。

那麼this->ui->webViewCut->page()->mainFrame()->addToJavaScriptWindowObject("QtObj", this);程式碼在什麼時候執行呢? 推薦是在QWebFrame的訊號javaScriptWindowObjectCleared發出的時候執行,所以我們可以在當前UI介面類的建構函式中新增下面的程式碼:

1 2 connect(ui->webViewCut->page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()), this, SLOT(populateJavaScriptWindowObject()));

然後在處理javaScriptWindowObjectCleared()訊號的槽函式中實現上述暴露功能:

1 2 3 4 void MainWindow::populateJavaScriptWindowObject() { ui->webViewCut->page()->mainFrame()->addToJavaScriptWindowObject("QtObj"this); }

根據Qt文件上對該訊號的描述javaScriptWindowObjectCleared()這個訊號會在我們呼叫QwebViewCut::load()載入新的url之前就觸發,我們在這個時候去處理這個訊號,將我們需要暴露的Qt物件暴露給即將載入的網頁

<4>. 將Qt的屬性暴露出去供js呼叫,使用如下方法:

1 Q_PROPERTY(int Qtvalue READ testValue WRITE setTestValue)

將上面的語句加入到類的宣告中,在private塊下面就可以,最後不需要以分號結尾,例如:

1 2 private: Q_PROPERTY(int Qtvalue READ testValue WRITE setTestValue)

這一行的作用是將屬性 Qtvalue 註冊到Qt的元物件系統中,在js中可以通過名字Qtvalue來訪問該屬性,但在js中訪問該屬性的時候假設Qt暴露給js的物件為QtObj,那麼在js中可以這樣訪問該屬性:

1 2 QtObj.Qtvalue = 10; //設定該屬性的時候會呼叫void setTestValue(int) alert(QtObj.Qtvalue) //獲取該屬性的時候會呼叫 int testValue()

Q_PROPERTY(int Qtvalue READ testValue WRITE setTestValue)的結構如下:

1 2 Q_PROPERTY( 型別   屬性名    READ     返回屬性值的函式    WRITE     設定屬性值的函式 ) int   Qtvalue           int testValue()          void setTestValue(int)

也就是說在js中我們可以直接使用Qtvalue,當獲取Qtvalue的值的時候會自動呼叫暴露物件的 int testValue() 函式 ,Qt規定其返回值必須與Q_PROPERTY語句中指定的型別相同,並且必須沒有引數。當我們為Qtvalue設定值的時候會呼叫暴露物件的void setTestValue(int)函式,該函式必須有一個int型別的引數(型別也必須與前面Q_PROPERTY語句中指定的型別相同),並且不能有返回值。

經過實驗int testValue()void setTestValue(int)函式的宣告在private區域也可以,好像無所謂。其實這兩個函式的名字是可以隨意定的,對js暴露的屬性名是Qtvalue,當訪問Qtvalue屬性的時候,會自動呼叫Q_PROPERTY宣告中READ後面指定的函式去獲取值,並且呼叫WRITE後面指定的函式去設定值,而不在乎這兩個函式的名字。

另外這兩個函式獲取的值或者設定的值從哪裡得來呢,我們可以在Qt物件中定義一個私有變數來儲存這個值,而這個私有變數的名字是無所謂的,甚至如果需要的話,我們也不必儲存這個值,直接在函式testValue裡面返回一個常量值,也就是說是否應該定義一個私有變數來儲存Qtvalue相關聯的屬性值,這個也不是必須的。

更多Qt QWidget與js的互動可以在Qt文件中搜索  The Qt WebKit Bridge關鍵字,其實Q_PROPERTY並不是專用於暴露屬性給js的,Q_PROPERTY是Qt元物件系統的一部分。

<5>. 如果在QWebview載入的網頁中有Flex應用程式,並且Qt中呼叫該QWebview載入的網頁中的js函式中需要呼叫flex程式暴露給js的介面,那麼還需要作如下設定:

"%appdata%\Macromedia\Flash Player\#Security\FlashPlayerTrust\"路徑下新建xxx.cfg檔案,將當前flex應用程式所在位置(也就是swf檔案所在的目錄)填寫到該檔案中即可,該xxx.cfg的名字是無所謂的,隨便什麼名字,在xxx.cfg檔案中指定的目錄路徑中的swf檔案的執行是被信任的。xxx.cfg檔案中可以指定多個目錄,每行一個。實際上%appdata%\Macromedia\Flash Player\#Security\FlashPlayerTrust\路徑下也可以有多個檔名不同的cfg檔案。xxx.cfg檔案中指定的目錄實際上可以直接指定為根目錄,例如swf檔案的路徑是F:/xxx/yyy/zzz/test.swf,那麼我們新建的xxx.cfg中的內容的第一行可以直接指定為F:/即可。

其實FlexBuilder在建立專案的時候,其生成的swf所在的目錄都被新增到了%appdata%\Macromedia\Flash Player\#Security\FlashPlayerTrust\下面的flashbuilder.cfg中了,所以使用FlexBuilder除錯專案的時候,執行的swf都是被信任的。

回到頂部

使用QSS

QSS是Qt中的樣式表,用來定義Qt中控制元件的外觀,實際上QSS的語法與屬性大量參考了CSS,如果你有web的CSS開發經驗,幾乎沒有任何障礙就可以掌握QSS,QSS中的選擇器基本上與CSS中的相同,但是QSS只有幾種常用的選擇器型別。

QSS中選擇器的型別:

<1>. 型別選擇器,例如:QPushButton{} 設定所有型別是QPushButton或者繼承自QPushButton的控制元件的樣式。
<2>. 屬性選擇器,例如:QPushButton[flat="false"]{} 設定所有flat屬性是false的QPushButton控制元件的樣式。
<3>. 類選擇器,例如:.QPushButton{} 設定所有QPushButton的樣式,但是不會設定繼承自QPushButton型別的控制元件的樣式,QSS中的類選擇器與CSS中的含義不同,QSS中的類選擇器點號後面指定的類的名稱,而CSS中的類選擇器中的點號後面指定的是HTML標籤中的class屬性的名稱。
<4>. ID選擇器,例如:#okButton{} 設定所有物件名(object name)為okButton的控制元件的樣式。
<5>. 後代選擇器,例如:QDialog QPushButton{} 設定所有QDialog中的QPushButton子控制元件的樣式,只要是QDialog的子控制元件都會應用該樣式,包括直接或非直接的子控制元件。
<5>. 直接子選擇器:例如 QDialog > QPushButton{} 設定所有是QDialog直接子控制元件的QPushButton的樣式。
<6>. QSS支援選擇器分組,支援選擇器組合,例如:QPushButton#okButton{} 設定所有ID為okButton的QPushButton控制元件的樣式。#okButton,#cancelButton{} 設定id為okButton、cancelButton的控制元件的樣式。

那麼如何在Qt中使用這些QSS設定控制元件的外觀呢,一般在程式碼中通過呼叫控制元件物件的setStyleSheet(QString)成員函式進行設定,引數即是QSS字串。例如:

1 ui->btnTest->setStyleSheet("border:1px solid red;");//設定按鈕的邊框

另外我們可以將所有的QSS放到檔案中,例如main.qss,然後將該檔案新增到Qt的資原始檔中,在主UI介面中載入該main.qss檔案,並呼叫主UI介面類的成員函式設定其下控制元件的樣式:

1

相關推薦

關於QT系統總結非常全面

編譯環境與開發流程 開發QT有兩種IDE可以使用,一種是使用 VS + Qt 的外掛,另一種就是使用QtCreator工具。前一種是微軟的工具,用的都比較多容易上手,缺點是訊號槽的支援不太好,需要手寫,不能自動生成,另外可能有中文編碼的問題。後一種是Qt的官方IDE,智慧提

MySQL/Oracle資料庫優化總結非常全面

MySQL資料庫優化的八種方式(經典必看) 引言: 關於資料庫優化,網上有不少資料和方法,但是不少質量參差不齊,有些總結的不夠到位,內容冗雜 偶爾發現了這篇文章,總結得很經典,文章流量也很大,所以拿到自己的總結文集中,積累優質文章,提升個人

unity3d的GUI元素的界面坐標系統總結有公式

lin oid con app rgb 公式 nbsp 多說 tar 大家好,我是孫廣東,我近期在做一個遊戲,UI就是使用了系統提供的GUI。遇到非常多的問題。相信大家經常使用的就是NGUI或者2DTOOLKIT.活不多說。 Unity有四個重要的坐標系統。 能夠查看例

Qt學習總結C魚之信號與槽01

Qt 學習 總結 C魚 自動關聯 第一種自然是手動關聯了,只要調用connect函數就能實現自動關聯。這裏重點講第二種,自動關聯:為了實現槽函數自動進行關聯,對於Qt窗口部件已經提供的信號,可按照以下規範命名:void on_&lt;窗口部件名稱&gt;_&lt;信號名

Qt學習總結C魚之路徑參數引用

Qt學習總結(C魚)之路徑參數引用1.引用相對路徑: 例如: QCursor cursor(QPixmap("1.png")); 問題:會發現引用失敗,這是因為相對路徑都是從當前工作目錄開始找起文件的。可以通過以下函數獲取當前工作目錄: bool QDir::setCurrent ( co

Java 多執行緒面試題及答案非常全面

這篇文章主要是對多執行緒的問題進行總結的,因此羅列了40個多執行緒的問題。 這些多執行緒的問題,有些來源於各大網站、有些來源於自己的思考。可能有些問題網上有、可能有些問題對應的答案也有、也可能有些各位網友也都看過,但是本文寫作的重心就是所有的問題都會按照自己的理解回答一遍,不會去看網上的

Java系統總結學習目錄

目錄 JVM 框架知識 工具 效能優化 資料庫知識 大資料知識 架構師 新技術 JVM JVM記憶體結構 Java記憶體模型 垃圾回收 JVM引數及調優 Java物件模型 HotSpot 類載入機制

織夢dedecms標籤大全非常全面

織夢(dedecms)標籤大全:下面介紹的都是織夢繫統常用的一些標籤,通過這些標籤,站長們可以任意的修改自己織夢網站的模板,該頁面會不定時更新,大家可以用ctrl+F實現搜尋。 網站名稱:{dede:global.cfg_webname/} 網站根網址:{dede:glo

程序與執行緒總結比較全面

1.程序和執行緒 1.1 概述: 程序是具有一定獨立功能的程式關於某個資料集合上的一次執行活動,程序是系統進行資源分配和排程的一個獨立單位. 執行緒是程序的一個實體,是CPU排程和分派的基本單位,它是比程序更小的能獨立執行的基本單位.執行緒自己基本上不擁有系統資源,只擁有一點在執行中必不

java後端 三方登入之微信登入 開發詳細流程以及遇到過的坑 總結非常詳細 2017-12-26

上一篇寫了qq登入,其實微信登入和qq登入幾乎一個邏輯,一個寫完,另一個就簡單了 一、第三方登入介面申請流程,並且拿到code 這裡的獲取key和id也是有2個地方,一個是微信公眾平臺,一個是微信開放

Spring NoSuchBeanDefinitionException六大原因總結非常實用【新增第三方jar的類 作Service層的依賴失敗 因為此錯。xml定義“同名bean”解決】

=====給了我思路。【新增第三方jar的類 作Service層的依賴失敗 因為此錯。xml定義“同名bean”解決】======1. OverviewIn this article, we are discussing the Springorg.springframewo

Qt 系統托盤加hover效果

界面 lose bytearray blog ndb pex 打開 tip tin 最近項目需要添加系統托盤,本來Qt的QSystemTrayIcon可以實現的,但是要求要添加hover效果,並顯示未讀消息(就和qq的托盤差不多,移動上去顯示未讀列表),加了這個要求QSys

ROS探索總結十二——坐標系統

時間 形象 ins left 添加 href node continue 我們 ubuntu 14.04 indigo版本 轉摘自:http://www.guyuehome.com/265 一、tf簡介 1、安裝turtle包 1 rosdep install tu

Linux學習總結十六系統用戶及用戶組管理

useradd groupadd usermod passwd mkpasswd 先來認識兩個文件/etc/passwd/etc/shadow我們打印出首尾三行,來了解下:每行由:分割為7段,每段含義為:第一段:用戶名,比如root 用戶,普通用戶test,lv,test1第二段:早期存放

Linux 學習總結二十三系統管理技巧2

nload free ps netstat tcpdump 1 監控io性能 nload -x %util 項 數字過大,說明io性能差,有可能是磁盤老化,或者磁盤本身故障。iotop 命令 也是動態顯示,類似於top ,可以查看磁盤的讀寫速度查看內存使用情況 2 free -h 查看內存

教你寫Makefile非常全面,講解很清晰

 Makefile 值得一提的是,在Makefile中的命令,必須要以[Tab]鍵開始。       什麼是makefile?或許很多Winodws的程式設計師都不知道這個東西,因為那些Windows的IDE都為你做了這個工作,但我覺

python一標準異常總結大全非常

Python標準異常總結 AssertionError 斷言語句(assert)失敗 AttributeError 嘗試訪問未知的物件屬性 EOFError 使用者輸入檔案末尾標誌EOF(C

學生資訊管理系統總結——優化篇

enter,esc鍵設定 確定按鈕屬性default------→true 取消按鈕屬性cancel------→true 窗體中心位置展現 首先將窗體介面通過滑鼠拖拽,達到介面大小適中 接著檢視屬性中的height,width屬性數值,將該數值填入下面程式碼中 from中新增以

學生資訊管理系統總結

限制文字框輸入的必須是數字 Private Sub Text1_KeyPress(KeyAscii As Integer) If (KeyAscii < 48 Or KeyAscii > 57) Then keyAscii = 0 End

學生資訊管理系統總結

Option Explicit ——強制變數宣告,若不宣告,則會顯示為variant(變體)型別,即未被宣告變數數 據型別。 Count ——用於計數 ADODB ——動態資料鏈接物件(Active Data Objects Data Base),它是一種 PHP 存取資