最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Qt自定義Widget實現(xiàn)互斥效果詳解

 更新時間:2022年01月24日 09:02:11   作者:中國好公民st  
在使用Qt時,可能會遇到這種問題:多個控件互斥,類似于QRadiButton控件,但又不是單純的QRadioButton控件,互斥的可能是一個窗口,也可能是幾個按鈕,等等多種情況。本文將介紹利用Qt自定義Widget實現(xiàn)的互斥效果,需要的可以參考一下

前沿

什么叫做自定義Widget實現(xiàn)互斥效果呢?

在使用Qt做一個界面美觀性比較強的功能時,可能會遇到這種問題:多個控件互斥,類似于QRadiButton控件,但又不是單純的QRadioButton控件,互斥的可能是一個窗口,也可能是幾個按鈕,等等多種情況。

這里我只是列舉了一個簡單的互斥例子,雖然簡單,但是包含了各種坑,有需要的掘友們可以小筆記們記一下,尤其是對Qt新手來說,還是很有必要的。

由效果圖可以看出創(chuàng)建了3個自定義widget,點擊其中一個時,另外兩個背景色以及文本顏色變化,處于選中狀態(tài)。

接下來,針對效果圖展示的功能進行逐一講解,包含了知識點以及踩坑記錄。

功能實現(xiàn)

實現(xiàn)自定義互斥widget過程中遇到了如下知識點以及問題,看看有沒有你曾經(jīng)遇到的或者是剛好需要的功能吧!

知識點

1:Widget模擬按鈕的四態(tài)功能,包括了:常態(tài)、按下、聚焦、禁用

2:Widget自定義類的背景色設(shè)置以及文本內(nèi)容風格設(shè)置

3:如何讓多個widget實現(xiàn)互斥效果

問題

1:自定義Widget背景色設(shè)置之后為什么不生效?

針對上述知識點以及問題來講述這個簡單的功能吧!

講解知識點1

使用Widget模擬按鈕的四態(tài)功能,需要用到Widget自身的消息:鼠標按下,鼠標進入、鼠標離開。

virtual void mousePressEvent(QMouseEvent *event); //鼠標按下響應(yīng)消息
virtual void enterEvent(QEvent *event); //鼠標進入響應(yīng)消息
virtual void leaveEvent(QEvent *event); //鼠標離開響應(yīng)消息

有沒有人會問道,為什么沒有mouseMoveEvent消息?

解答:在Qt中直接使用mouseMoveEvent消息鼠標是無法觸發(fā)的,必須要設(shè)置setMouseTracking(true)讓鼠標跟蹤事件在當前窗口處于有效狀態(tài)。

根據(jù)使用的具體情況是否需要設(shè)置這個功能。當前的小demo中,只是做圖片的轉(zhuǎn)換,沒有必要在mouseMove中一直消耗資源。

(題外話:在MFC框架下的鼠標mosemove事件是直接可用的不需要進行特殊設(shè)置)

鼠標進入到widget之后,就可以標記為鼠標一直在該widget中活動,除非觸發(fā)了leaveEvent消息。

鼠標按下響應(yīng)消息

void QCustomWidget::mousePressEvent(QMouseEvent *event)
{
	this->SetWidgetStyle(Style_Down);
	QWidget::mousePressEvent(event);
}

當前采用的枚舉類型:鼠標按下響應(yīng)。

鼠標進入widget響應(yīng)消息

void QCustomWidget::enterEvent(QEvent *event)
{
	this->SetWidgetStyle(Style_Focus);
	QWidget::enterEvent(event);
}

當前采用的枚舉類型:鼠標聚焦狀態(tài),使用進入消息代替了mousemove消息。

如果大家打日志會發(fā)現(xiàn),該觸發(fā)函數(shù)只會在鼠標進入的時候走一次,當鼠標持續(xù)在widget內(nèi)部移動時是不觸發(fā)的,極大的減少了消息處理。

鼠標離開widget響應(yīng)消息

void QCustomWidget::leaveEvent(QEvent *event)
{
	this->SetWidgetStyle(Style_Normal);
	QWidget::leaveEvent(event);
}

當前采用的枚舉類型:鼠標離開狀態(tài)。

我只是展示了最簡單的離開設(shè)置,有一點需要考慮,當前widget如果處于按下狀態(tài),此刻鼠標離開了,該如何展示呢?

難道還要顯示常態(tài)風格嗎?

答案肯定是NO!

雖然鼠標已經(jīng)移開,但是選中狀態(tài)已經(jīng)由常態(tài)變成了按下狀態(tài)。在程序中我們需要用一個bool值變量來記錄當前widget是否已經(jīng)被選中過,如果選中過,當鼠標離開時就需要更改為選中狀態(tài)

修改如下所示:

if (m_bClickedState == true)
{
	this->SetWidgetStyle(Style_Down);
}
else
	this->SetWidgetStyle(Style_Normal);

講解知識點2

在程序中對于模擬的狀態(tài)采用了枚舉的類型進行表示。

類型說明
Style_Normal鼠標未做任何操作的初始狀態(tài)
Style_Down鼠標在wiget中進行了按下操作
Style_Focus鼠標在widget中進行移動時操作狀態(tài)
Style_Disable當前widget處于進行狀態(tài)

每一個widget中都展示了相同的內(nèi)容:編號,文本

因為只是做了展示功能,所以全部使用了QLabel控件

QLabel *m_labNumber; //編號類指針

QLabel *m_LabContent; //內(nèi)容類指針

對應(yīng)的實際處理

void QCustomWidget::SetWidgetStyle(ENUM_WidgetStyle enumStyle)
{
	//TODO:設(shè)置widget風格
	QString qsStyle = "", gStyleNumberNormal = "", gStyleContentNormal = "";
	switch (enumStyle)
	{
	case Style_Normal: //常態(tài)顯示
	{
		//設(shè)置:背景
		qsStyle = "QWidget{background-color:#FFD700}";
		//設(shè)置:編號風格
		gStyleNumberNormal = "QLabel{color:#666666; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
		//設(shè)置:內(nèi)容風格
		gStyleContentNormal = "QLabel{color:#666666; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
	}
		break;
	case Style_Down: //按下
	{
		//設(shè)置:背景
		qsStyle = "QWidget{background-color:#FFB6C1}";
		//設(shè)置:編號風格
		gStyleNumberNormal = "QLabel{color:#0000FF; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
		//設(shè)置:內(nèi)容風格
		gStyleContentNormal = "QLabel{color:#00FFFF; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
	}
		break;
	case Style_Focus: //聚焦
	{
		//設(shè)置:背景
		qsStyle = "QWidget{background-color:#FFF0F5}";
		//設(shè)置:編號風格
		gStyleNumberNormal = "QLabel{color:#98FB98; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
		//設(shè)置:內(nèi)容風格
		gStyleContentNormal = "QLabel{color:#98FB98; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
	}
		break;
	case Style_Disable: //禁用
	{
		//設(shè)置:背景
		qsStyle = "QWidget{background-color:#DCDCDC}";
		//設(shè)置:編號風格
		gStyleNumberNormal = "QLabel{color:#696969; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
		//設(shè)置:內(nèi)容風格
		gStyleContentNormal = "QLabel{color:#696969; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
	}
		break;
	default:
		break;
	}
	this->setStyleSheet(qsStyle);
	m_labNumber->setStyleSheet(gStyleNumberNormal);
	m_labContent->setStyleSheet(gStyleContentNormal);
}

根據(jù)不同的類型對應(yīng)的背景風格也不同。大家可以將代碼帶入,運行查看下效果,是不是跟我展示的效果一致呢?

哈哈!如果你嘗試了,就會發(fā)現(xiàn)是這個樣子的效果:

為什么只能顯示文字,我的背景呢?去了哪里?我不是已經(jīng)設(shè)置了嗎?

很多Qt新手在這里都會遇到這樣的問題,于是開啟了各種搜索模式,嘗試各種方法,有的時候改著改著就對了,也就忽略了這個問題。

當我們創(chuàng)建一個自定義widget時,通用的方法使用new實例的方式,在new的過程中,為了層級關(guān)系好打理已經(jīng)父子關(guān)系明確,都會傳入this作為新創(chuàng)建窗口的父指針。

一旦我們傳入了this指針之后,并未在自定義Widget中做任何處理時,此時就會出現(xiàn)這樣的情況。

子類繼承了父窗口的風格樣式。

一般遇到這種情況時,會有兩種處理方式:重寫當前窗口的paintEvent函數(shù),設(shè)置不沿用父窗口風格

為了方便起見,當窗口繪制的背景圖不復(fù)雜的情況下都會采用第二種方式設(shè)置:

this->setAttribute(Qt::WA_StyledBackground);

在當前自定義widget類構(gòu)造函數(shù)中設(shè)置上述代碼后,之前出現(xiàn)的設(shè)置了背景風格卻看不見的問題就迎刃而解了。

講解知識點3

如何實現(xiàn)多個widget之間的互斥呢?

使用過QRadioButton控件的掘友們都知道,該控件想要設(shè)置互斥只需要簡單的設(shè)置函數(shù)就可以了。

對于我們自定義的widget來說,是不存在這種函數(shù)的,互斥效果只能是手動用代碼設(shè)置并根據(jù)選中與非選中狀態(tài)來更換對應(yīng)的展示效果。

假設(shè),當前選中了“內(nèi)容1”的自定義Widget,此時需要在Widget中鼠標按下響應(yīng)中觸發(fā)一個消息,通知外界,當前自定義Widget做了按下操作,需要做特殊的處理

void QCustomWidget::mousePressEvent(QMouseEvent *event)
{
	this->SetWidgetStyle(Style_Down);
	emit Msg_SendClicked();
	QWidget::mousePressEvent(event);
}

在調(diào)用自定義Widget的父類中響應(yīng)對應(yīng)的槽函數(shù)做特殊處理。

總結(jié)

到這里實現(xiàn)自定義Widget互斥效果就簡單實現(xiàn)了。

對于互斥操作的實現(xiàn)很簡單,最最需要掌握的就是如何設(shè)置widget的背景。

很多情況下子窗口與父窗口嵌套層級過多時,這種問題最容易出現(xiàn)了,因為我們在每次創(chuàng)建一個新widget對象時,最好的方式每次都不沿用父窗口的樣式。

到此這篇關(guān)于Qt自定義Widget實現(xiàn)互斥效果詳解的文章就介紹到這了,更多相關(guān)Qt Widget實現(xiàn)互斥內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C++入門之模板基礎(chǔ)講解

    C++入門之模板基礎(chǔ)講解

    這篇文章主要為大家介紹了C++入門之模板基礎(chǔ),具有一定的參考價值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2021-11-11
  • 解析c中stdout與stderr容易忽視的一些細節(jié)

    解析c中stdout與stderr容易忽視的一些細節(jié)

    本篇文章是對在c語言中stdout與stderr容易忽視的一些細節(jié)進行了詳細的分析介紹,需要的朋友參考下
    2013-05-05
  • c++面試題字符串拷貝函數(shù)示例

    c++面試題字符串拷貝函數(shù)示例

    這個也算是企業(yè)招工里面比較常見的一道筆試面試題了,非常簡單。個人覺得考的主要是對指針使用的熟練程度,還有對字符串類內(nèi)部原理的掌握程度
    2013-12-12
  • 基于QT實現(xiàn)簡單的鬧鐘

    基于QT實現(xiàn)簡單的鬧鐘

    這篇文章主要為大家詳細介紹了如何基于QT實現(xiàn)一個簡單的鬧鐘小程序,文中的示例代碼講解詳細,具有一定的學(xué)習價值,有需要的小伙伴可以參考一下
    2025-02-02
  • C++ 關(guān)于MFC List Control 控件的總結(jié)

    C++ 關(guān)于MFC List Control 控件的總結(jié)

    這篇文章主要介紹了C++ 關(guān)于MFC List Control 控件的總結(jié)的相關(guān)資料,十分的詳細,有需要的朋友可以參考下
    2015-06-06
  • C++中如何使用引用避免內(nèi)存復(fù)制

    C++中如何使用引用避免內(nèi)存復(fù)制

    C++引用是一種強大的工具,可以避免在函數(shù)調(diào)用過程中發(fā)生的常見內(nèi)存復(fù)制問題,本文主要介紹了C++中如何使用引用避免內(nèi)存復(fù)制,感興趣的可以了解一下
    2023-10-10
  • C語言圖文并茂講解分支語句用法

    C語言圖文并茂講解分支語句用法

    分支結(jié)構(gòu)的執(zhí)行是依據(jù)一定的條件選擇執(zhí)行路徑,而不是嚴格按照語句出現(xiàn)的物理順序。分支結(jié)構(gòu)的程序設(shè)計方法的關(guān)鍵在于構(gòu)造合適的分支條件和分析程序流程,根據(jù)不同的程序流程選擇適當?shù)姆种дZ句
    2022-04-04
  • C++如何判斷一個數(shù)是不是素數(shù)

    C++如何判斷一個數(shù)是不是素數(shù)

    這篇文章主要介紹了C++如何判斷一個數(shù)是不是素數(shù),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-07-07
  • C語言實現(xiàn)棧的示例詳解

    C語言實現(xiàn)棧的示例詳解

    棧是一種特殊的線性表,只允許從一端進出數(shù)據(jù),稱為后進先出,先進后出。本文主要為大家介紹了C語言實現(xiàn)棧的示例代碼,感興趣的可以了解一下
    2022-06-06
  • C語言開發(fā)實現(xiàn)井字棋及電腦落子優(yōu)化示例詳解

    C語言開發(fā)實現(xiàn)井字棋及電腦落子優(yōu)化示例詳解

    以前上課經(jīng)常和同桌玩起井字棋,那么我們就當我們回憶童年,現(xiàn)在也用C語言來實現(xiàn)井字棋,本次代碼相對于初階的井字棋,在電腦下棋代碼部分做了優(yōu)化,使得電腦更加具有威脅
    2021-11-11

最新評論

裕民县| 桂阳县| 江北区| 巫山县| 潼关县| 芦溪县| 安陆市| 成武县| 乐平市| 浦城县| 盖州市| 霸州市| 灵武市| 平泉县| 稷山县| 观塘区| 钟祥市| 安平县| 米脂县| 潜江市| 秦皇岛市| 栾城县| 巴塘县| 大足县| 金华市| 台安县| 中卫市| 太仓市| 大关县| 新蔡县| 东山县| 工布江达县| 诏安县| 威信县| 青浦区| 五指山市| 塔河县| 盐边县| 九龙城区| 扶沟县| 大邑县|