Qt實(shí)現(xiàn)小功能之復(fù)雜抽屜效果詳解
在Qt自帶的控件中,也存在抽屜控件:QToolBar。但是,該控件有個(gè)缺點(diǎn):一次只能展開一個(gè)抽屜信息,無法實(shí)現(xiàn)多個(gè)展開。為此,實(shí)現(xiàn)了如下效果的程序:
下面對(duì)這種實(shí)現(xiàn)效果進(jìn)行講解~
功能講解
開發(fā)環(huán)境:VS2017 + Qt5.14.2 64位
實(shí)現(xiàn)的核心技術(shù):
1:QScrollArea的應(yīng)用。
2:垂直布局的應(yīng)用。
根據(jù)展示效果可以發(fā)現(xiàn):一個(gè)標(biāo)題下面對(duì)應(yīng)了一個(gè)顯示窗口,標(biāo)題的下拉按鈕控制了粉色窗口的顯示和隱藏。
接下來,由內(nèi)向外進(jìn)行實(shí)現(xiàn)。
自定義標(biāo)題widget
類名:QSingleTitleWidget
代表了每一個(gè)單獨(dú)的標(biāo)題窗口。包含了兩個(gè)控件:QLabel、QCheckBox,分別展示標(biāo)題名稱以及控制是否展示對(duì)應(yīng)的內(nèi)容窗口
標(biāo)題名稱控件的創(chuàng)建
QString qsLabelStyle = "QLabel{color:#333333; font-family:Microsoft YaHei UI; font-size:18px;} QLabel{background-color: transparent}"; m_labTitle = new QLabel(this); m_labTitle->setGeometry(10, 0, 200, 60); m_labTitle->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); m_labTitle->setStyleSheet(qsLabelStyle); m_labTitle->show();
QCheckBox控件的創(chuàng)建
QString qsCheckStyle = "QCheckBox{color:#333333;font-family:Microsoft YaHei UI;font-size:14px;}" "QCheckBox::indicator::checked{image:url(:/QMultipleToolBarWidget/image/jd_zk_s.png)}" "QCheckBox::indicator::unchecked{image:url(:/QMultipleToolBarWidget/image/jd_sq_n.png)}"; m_check = new QCheckBox(this); m_check->setGeometry(500, 5, 50, 60); m_check->setStyleSheet(qsCheckStyle); connect(m_check, &QCheckBox::clicked, this, &QSingleTitleWidget::OnCheckShowState); m_check->show(); m_check->setChecked(false);
在標(biāo)題類(QSingleTitleWidget)中需要實(shí)現(xiàn)QCheckBox的響應(yīng)消息,通知外界該標(biāo)題類對(duì)應(yīng)的內(nèi)容類是顯示還是隱藏狀態(tài)。
"setChecked(false)":默認(rèn)窗口一創(chuàng)建就讓粉色窗口處于隱藏狀態(tài)。
對(duì)于QCheckBox的消息的實(shí)現(xiàn),如下:
void QSingleTitleWidget::OnCheckShowState(bool checked /*= false*/) { emit Msg_SendShowState(m_nNum, checked); }
其中,m_nNum是當(dāng)前標(biāo)題窗口的編號(hào),在通知外界的同時(shí)也需要告訴外界,是哪個(gè)窗口發(fā)生了變化!
補(bǔ)充一點(diǎn):在QSingleTitleWidget類中也可以不實(shí)現(xiàn)QCheckBox響應(yīng)消息,直接使用QWidget::mousePressEvent消息做處理,這里不再詳細(xì)說明!
自定義內(nèi)容Widget
類名:QSingleContentWidget
代表了每一個(gè)單獨(dú)的內(nèi)容窗口。僅有一個(gè)控件:QLabel,只是用于提示窗口的高度。
其實(shí)在實(shí)際開發(fā)中,可以展示更豐富的內(nèi)容,這里只是展示了不同高度。
創(chuàng)建顯示高度描述控件
QString qsLabelStyle = "QLabel{color:#333333; font-family:Microsoft YaHei UI; font-size:18px;} QLabel{background-color: transparent}"; m_labContent = new QLabel(this); m_labContent->setStyleSheet(qsLabelStyle); m_labContent->setAlignment(Qt::AlignVCenter | Qt::AlignLeft); m_labContent->show();
設(shè)置具體的高度值
void QSingleContentWidget::SetContent(int nHeight) { QString qsContent = QStringLiteral("當(dāng)前窗口高度是:") + QString::number(nHeight); m_labContent->setGeometry(10, 10, 540, nHeight-20); m_labContent->setText(qsContent); }
以上1、2兩部分內(nèi)容分別描述了標(biāo)題widget、內(nèi)容widget,下面需要?jiǎng)?chuàng)建一個(gè)承載這些內(nèi)容的widget載體,將在QScrollArea中使用。
QScrollArea中widget實(shí)現(xiàn)
類名:QScrollAreaWidget
該類是一個(gè)承載多個(gè)標(biāo)題、內(nèi)容的widget,也是直接由外部調(diào)用的類。
假設(shè):傳入一個(gè)std::vector<int>
的容器,容器的多少大小代表的是標(biāo)題的個(gè)數(shù),int值是隨機(jī)生成的高度值。
但是,到了真正業(yè)務(wù)應(yīng)用中時(shí),這里的int沒準(zhǔn)就是一個(gè)結(jié)構(gòu)體,或者是一個(gè)數(shù)據(jù)指針,無論是什么,處理方式都是一樣的。
對(duì)外開放接口:
void QScrollAreaWidget::SetScrollAreaData(std::vector<int> vetWidget) { //數(shù)據(jù)處理 }
根據(jù)vetWidget的大小創(chuàng)建出對(duì)應(yīng)的數(shù)據(jù)組(一個(gè)標(biāo)題、一個(gè)內(nèi)容)
直接上全部代碼~
int nTop = 0; for (int i = 0; i < vetWidget.size(); i++) { //創(chuàng)建:標(biāo)題 QSingleTitleWidget *widgetTitle = new QSingleTitleWidget(this); widgetTitle->setFixedSize(560, 60); widgetTitle->SetTitleContent(i); bool bShowState = i == 0 ? true : false; widgetTitle->SetShowState(bShowState); widgetTitle->show(); connect(widgetTitle, &QSingleTitleWidget::Msg_SendShowState, this, &QScrollAreaWidget::MsgReceivedTitleControlShowState); m_vetTitleWidget.push_back(widgetTitle); m_layout.addWidget(widgetTitle); nTop += 60 + 5; //創(chuàng)建:內(nèi)容 QSingleContentWidget *widgetContent = new QSingleContentWidget(this); widgetContent->setFixedSize(QSize(560, vetWidget[i])); widgetContent->SetContent(vetWidget[i]); if (bShowState == true) { widgetContent->show(); nTop += vetWidget[i] + 5; } else { widgetContent->hide(); } m_mapContentWidget.insert(std::make_pair(i, widgetContent)); m_layout.addWidget(widgetContent); } m_layout.addStretch(0); m_layout.setSpacing(5); this->setLayout(&m_layout); m_nTotalHeight = nTop; this->setFixedSize(QSize(560, nTop));
代碼講解:
1:創(chuàng)建標(biāo)題類:QSingleTitleWidget、創(chuàng)建內(nèi)容類:QSingleContentWidget。
這兩個(gè)類是一對(duì)一對(duì)應(yīng)的。其中,這里有個(gè)小邏輯處理,當(dāng)編號(hào)是0時(shí)(也就是第一組數(shù)據(jù)時(shí))默認(rèn)處于顯示狀態(tài)。
采用了三目運(yùn)算符,方便簡(jiǎn)單:bool bShowState = i == 0 ? true : false;
并且,在創(chuàng)建QSingleContentWidget類時(shí),根據(jù)是否顯示狀態(tài)來控件該類是否顯示。
2:消息處理
之前在QSingleTitleWidget類中發(fā)送了一個(gè)QCheckBox的消息,在這里就運(yùn)用到該消息了。
Msg_SendShowState參數(shù)值=true時(shí),代表展示QSingleContentWidget類內(nèi)容;反之,隱藏QSingleContentWidget類的內(nèi)容。
3:垂直布局應(yīng)用
每創(chuàng)建一個(gè)新的widget,需要將widget添加到布局中:m_layout.addWidget(widgetTitle);
最后,需要在當(dāng)前類中綁定布局:this->setLayout(&m_layout);
4:nTop值的意義
每創(chuàng)建一個(gè)類都需要對(duì)nTop進(jìn)行追加,主要是為了擴(kuò)大QScrollArea子窗口widget的大小,其實(shí)在使用布局后不使用也沒有關(guān)系,但是為了能夠讓我們控制widget的高度,最好主動(dòng)進(jìn)行設(shè)置。
QScrollArea子窗口的提升
從Qt Designer中拖出來的QScrollArea控件,默認(rèn)會(huì)自帶一個(gè)widget子控件,上述3下的功能就是對(duì)子控件的重寫,那么該如何綁定呢?
選中提升后,出現(xiàn)下面頁(yè)面
紅框里面就是需要提升的類文件以及類名。
注意:設(shè)置了提升的類名稱后,默認(rèn)頭文件會(huì)自動(dòng)添加,但是該頭文件是不區(qū)分大小寫!這里一定要改成與實(shí)際的頭文件名稱保持一致!
剛開始做的時(shí)候未區(qū)分大小寫,結(jié)果找了半天才找到原因,這也跟Qt版本有關(guān)系,最好與我們提升的類一一對(duì)應(yīng)!
到此這篇關(guān)于Qt實(shí)現(xiàn)小功能之復(fù)雜抽屜效果詳解的文章就介紹到這了,更多相關(guān)Qt復(fù)雜抽屜效果內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言中g(shù)etchar函數(shù)詳解看這一篇就夠了(函數(shù)功能、使用、返回值)
getchar讀取字符的函數(shù),今天通過本文給大家介紹C語(yǔ)言中g(shù)etchar函數(shù)簡(jiǎn)介用法示例詳解,感興趣的朋友跟隨小編一起看看吧2023-02-02利用C++簡(jiǎn)單實(shí)現(xiàn)順序表和單鏈表的示例代碼
這篇文章主要給大家介紹了關(guān)于利用C++簡(jiǎn)單實(shí)現(xiàn)順序表和單鏈表的方法,文中給出了詳細(xì)的示例代碼供大家參考學(xué)習(xí),需要的朋友可以參考借鑒,下面來跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-08-08C++實(shí)現(xiàn)矩陣原地轉(zhuǎn)置算法
這篇文章主要介紹了C++實(shí)現(xiàn)矩陣原地轉(zhuǎn)置算法,非常經(jīng)典的算法,需要的朋友可以參考下2014-08-08C++中棧結(jié)構(gòu)建立與操作詳細(xì)解析
我們可以把棧理解成一個(gè)大倉(cāng)庫(kù),放在倉(cāng)庫(kù)門口(棧頂)的貨物會(huì)優(yōu)先被取出,然后再取出里面的貨物。而從數(shù)據(jù)的邏輯結(jié)構(gòu)來看,棧結(jié)構(gòu)起始就是一種線性結(jié)構(gòu)2013-10-10C++中的局部變量、全局變量、局部靜態(tài)變量、全局靜態(tài)變量的區(qū)別
本文主要介紹了C++中的局部變量、全局變量、局部靜態(tài)變量、全局靜態(tài)變量的區(qū)別。具有很好的參考價(jià)值,下面跟著小編一起來看下吧2017-02-02使用C語(yǔ)言遞歸與非遞歸實(shí)現(xiàn)字符串反轉(zhuǎn)函數(shù)char *reverse(char *str)的方法
本篇文章是對(duì)使用C語(yǔ)言遞歸與非遞歸實(shí)現(xiàn)字符串反轉(zhuǎn)函數(shù)char *reverse(char *str)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05C/C++靜態(tài)類和this指針詳解及實(shí)例代碼
這篇文章主要介紹了 C/C++靜態(tài)類和this指針詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02