欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

前沿

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

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

這里我只是列舉了一個(gè)簡(jiǎn)單的互斥例子,雖然簡(jiǎn)單,但是包含了各種坑,有需要的掘友們可以小筆記們記一下,尤其是對(duì)Qt新手來(lái)說(shuō),還是很有必要的。

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

接下來(lái),針對(duì)效果圖展示的功能進(jìn)行逐一講解,包含了知識(shí)點(diǎn)以及踩坑記錄。

功能實(shí)現(xiàn)

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

知識(shí)點(diǎn)

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

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

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

問(wèn)題

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

針對(duì)上述知識(shí)點(diǎn)以及問(wèn)題來(lái)講述這個(gè)簡(jiǎn)單的功能吧!

講解知識(shí)點(diǎn)1

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

virtual void mousePressEvent(QMouseEvent *event); //鼠標(biāo)按下響應(yīng)消息
virtual void enterEvent(QEvent *event); //鼠標(biāo)進(jìn)入響應(yīng)消息
virtual void leaveEvent(QEvent *event); //鼠標(biāo)離開(kāi)響應(yīng)消息

有沒(méi)有人會(huì)問(wèn)道,為什么沒(méi)有mouseMoveEvent消息?

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

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

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

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

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

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

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

鼠標(biāo)進(jìn)入widget響應(yīng)消息

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

當(dāng)前采用的枚舉類型:鼠標(biāo)聚焦?fàn)顟B(tài),使用進(jìn)入消息代替了mousemove消息。

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

鼠標(biāo)離開(kāi)widget響應(yīng)消息

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

當(dāng)前采用的枚舉類型:鼠標(biāo)離開(kāi)狀態(tài)。

我只是展示了最簡(jiǎn)單的離開(kāi)設(shè)置,有一點(diǎn)需要考慮,當(dāng)前widget如果處于按下?tīng)顟B(tài),此刻鼠標(biāo)離開(kāi)了,該如何展示呢?

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

答案肯定是NO!

雖然鼠標(biāo)已經(jīng)移開(kāi),但是選中狀態(tài)已經(jīng)由常態(tài)變成了按下?tīng)顟B(tài)。在程序中我們需要用一個(gè)bool值變量來(lái)記錄當(dāng)前widget是否已經(jīng)被選中過(guò),如果選中過(guò),當(dāng)鼠標(biāo)離開(kāi)時(shí)就需要更改為選中狀態(tài)

修改如下所示:

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

講解知識(shí)點(diǎn)2

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

類型說(shuō)明
Style_Normal鼠標(biāo)未做任何操作的初始狀態(tài)
Style_Down鼠標(biāo)在wiget中進(jìn)行了按下操作
Style_Focus鼠標(biāo)在widget中進(jìn)行移動(dòng)時(shí)操作狀態(tài)
Style_Disable當(dāng)前widget處于進(jìn)行狀態(tài)

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

因?yàn)橹皇亲隽苏故竟δ?,所以全部使用了QLabel控件

QLabel *m_labNumber; //編號(hào)類指針

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

對(duì)應(yīng)的實(shí)際處理

void QCustomWidget::SetWidgetStyle(ENUM_WidgetStyle enumStyle)
{
	//TODO:設(shè)置widget風(fēng)格
	QString qsStyle = "", gStyleNumberNormal = "", gStyleContentNormal = "";
	switch (enumStyle)
	{
	case Style_Normal: //常態(tài)顯示
	{
		//設(shè)置:背景
		qsStyle = "QWidget{background-color:#FFD700}";
		//設(shè)置:編號(hào)風(fēng)格
		gStyleNumberNormal = "QLabel{color:#666666; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
		//設(shè)置:內(nèi)容風(fēng)格
		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è)置:編號(hào)風(fēng)格
		gStyleNumberNormal = "QLabel{color:#0000FF; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
		//設(shè)置:內(nèi)容風(fēng)格
		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è)置:編號(hào)風(fēng)格
		gStyleNumberNormal = "QLabel{color:#98FB98; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
		//設(shè)置:內(nèi)容風(fēng)格
		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è)置:編號(hào)風(fēng)格
		gStyleNumberNormal = "QLabel{color:#696969; font-family:Microsoft YaHei UI; font-size:14px;} QLabel{background-color: transparent}";
		//設(shè)置:內(nèi)容風(fēng)格
		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ù)不同的類型對(duì)應(yīng)的背景風(fēng)格也不同。大家可以將代碼帶入,運(yùn)行查看下效果,是不是跟我展示的效果一致呢?

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

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

很多Qt新手在這里都會(huì)遇到這樣的問(wèn)題,于是開(kāi)啟了各種搜索模式,嘗試各種方法,有的時(shí)候改著改著就對(duì)了,也就忽略了這個(gè)問(wèn)題。

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

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

子類繼承了父窗口的風(fēng)格樣式。

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

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

this->setAttribute(Qt::WA_StyledBackground);

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

講解知識(shí)點(diǎn)3

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

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

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

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

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

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

總結(jié)

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

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

很多情況下子窗口與父窗口嵌套層級(jí)過(guò)多時(shí),這種問(wèn)題最容易出現(xiàn)了,因?yàn)槲覀冊(cè)诿看蝿?chuàng)建一個(gè)新widget對(duì)象時(shí),最好的方式每次都不沿用父窗口的樣式。

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

相關(guān)文章

  • win10系統(tǒng)VS2019配置點(diǎn)云庫(kù)PCL1.12.1的詳細(xì)流程

    win10系統(tǒng)VS2019配置點(diǎn)云庫(kù)PCL1.12.1的詳細(xì)流程

    這篇文章主要介紹了win10系統(tǒng)VS2019配置點(diǎn)云庫(kù)PCL1.12.1的教程與經(jīng)驗(yàn)總結(jié),本文記錄小白在配置過(guò)程中踩過(guò)的一些小坑,需要的朋友可以參考下
    2022-07-07
  • 看圖深入理解單鏈表的反轉(zhuǎn)

    看圖深入理解單鏈表的反轉(zhuǎn)

    今天遇到單向鏈表的反轉(zhuǎn)的問(wèn)題,于是靜下心來(lái)好好想了一番。下面這篇文章主要給大家介紹了關(guān)于單鏈表反轉(zhuǎn)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • C++ 命名空間詳解

    C++ 命名空間詳解

    這篇文章主要介紹了C++ 命名空間的的相關(guān)資料,文中示例代碼非常詳細(xì),供大家參考和學(xué)習(xí),感興趣的朋友可以了解下
    2021-11-11
  • C語(yǔ)言如何利用異或進(jìn)行兩個(gè)值的交換詳解

    C語(yǔ)言如何利用異或進(jìn)行兩個(gè)值的交換詳解

    最近在工作中遇到了兩個(gè)值交換的需求,發(fā)現(xiàn)自己對(duì)異或有些忘記,所以索性寫(xiě)出來(lái),方便以后需要的時(shí)候參考學(xué)習(xí),下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言如何利用異或進(jìn)行兩個(gè)值的交換的相關(guān)資料,需要的朋友可以參考下。
    2017-09-09
  • C++基于hook iat改變Messagebox實(shí)例

    C++基于hook iat改變Messagebox實(shí)例

    這篇文章主要介紹了C++基于hook iat改變Messagebox的方法,以實(shí)例形式展示了針對(duì)IAT(即導(dǎo)入地址表)以及hook的操作,有助于深入理解Windows程序設(shè)計(jì)原理,需要的朋友可以參考下
    2014-10-10
  • 約瑟夫環(huán)問(wèn)題(數(shù)組法)c語(yǔ)言實(shí)現(xiàn)

    約瑟夫環(huán)問(wèn)題(數(shù)組法)c語(yǔ)言實(shí)現(xiàn)

    這篇文章主要介紹了約瑟夫環(huán)問(wèn)題(數(shù)組法)c語(yǔ)言實(shí)現(xiàn),有需要的朋友可以參考一下
    2013-12-12
  • C/C++使用C語(yǔ)言實(shí)現(xiàn)多態(tài)

    C/C++使用C語(yǔ)言實(shí)現(xiàn)多態(tài)

    這篇文章主要介紹了C/C++多態(tài)的實(shí)現(xiàn)機(jī)制理解的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下,希望能給你帶來(lái)幫助
    2021-08-08
  • 一文帶你了解Qt中槽的使用

    一文帶你了解Qt中槽的使用

    這篇文章主要為大家詳細(xì)介紹了Qt中槽的使用教程,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Qt有一定的幫助,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2022-12-12
  • OpenCV實(shí)現(xiàn)簡(jiǎn)易標(biāo)定板

    OpenCV實(shí)現(xiàn)簡(jiǎn)易標(biāo)定板

    這篇文章主要為大家詳細(xì)介紹了OpenCV實(shí)現(xiàn)簡(jiǎn)易標(biāo)定板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • C語(yǔ)言版五子棋游戲的實(shí)現(xiàn)代碼

    C語(yǔ)言版五子棋游戲的實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言版五子棋游戲的實(shí)現(xiàn)代碼,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07

最新評(píng)論