Qt 過載QComboBox,實現右側刪除鍵
前言
最近在做一個專案,這個專案用到一個QComboBox
下拉框,做出來之後,功能都是能夠正常實現的。但是我想要實現之前看到的一個網頁的下拉框效果:
所以我就琢磨怎麼來實現這種效果。
方案
簡單來說,就是當QComboBox
有選中內容時,滑鼠移動到右側下拉箭頭時,下拉箭頭變成一個叉號,點選之後會將當前選中的內容刪除;
設定下拉箭頭圖示
首先,我想到了讓這個下拉箭頭變換圖示的方式,通過setProperty
來設定動態屬性,並設定樣式,來設定不同圖示。具體方式請看我之前寫的這篇博文Qt通過setProperty來達到設定控制元件的不同樣式表。然後將訊號currentIndexChanged
和設定圖示的槽函式連線起來,程式碼如下:
// 連線訊號
connect(this, SIGNAL(currentIndexChanged(int)),
this,SLOT(slot_setPopupType(int)));
void MyComboBox::slot_setPopupType(const int &index)
{
QString type;
// 根據當前下標來判斷是不是有內容
type = (index == -1 ? "popup" : "close");
// 設定屬性
setProperty("Type", type);
// 設定屬性後,必須重新重新整理一下樣式
style()->polish(this);
}
設定QComboBox內容為空
在實踐的過程中,我苦於清除按鍵的功能設計,怎樣才能讓QComboBox
的內容為空呢?
然後我搜尋後發現了這個
setCurrentIndex(-1);
當設定當前下標為-1時,就會將QComboBox
的內容置空;
自定義showPopup函式
如果你需要對下拉的過程進行自定義,就需要過載函式showPopup
。我這裡不需要進行自定義,所以我就沒有進行過載了;
定位滑鼠
但是,我們要怎麼確定滑鼠按下的位置是下拉框呢?
我最開始的方案是根據滑鼠點選的位置來確定,但是根據你樣式表設定的不同,你的這個下拉箭頭的大小就會不同,我想盡了各種辦法,都沒有找到怎麼去獲取這個下拉箭頭的大小的方法,所以獲取的位置就可能會因為不同的樣式會有偏差。後面我想到自帶的QComboBox
不是有對下拉框進行點選事件嗎?或許能從原始碼裡找到答案。
這裡重要的點在
sc == QStyle::SC_ComboBoxArrow
看到這裡,我就知道要怎麼去判斷滑鼠點選的位置是下拉框了;
if (property("Type") == "close") {
// 當sc == SC_ComboBoxArrow代表,按下的位置為下拉箭頭的位置
if (e->button() == Qt::LeftButton
&& sc == QStyle::SC_ComboBoxArrow) {
setCurrentIndex(-1);
} else {
QComboBox::showPopup();
}
return;
}
遮蔽滑鼠右鍵
然後又出現了一個滑鼠右擊這個comboBox,也會將下拉框展開的問題,所以我們需要將滑鼠右鍵進行遮蔽;
if (e->button() == Qt::RightButton) {
return;
}
最終控制下拉程式碼
void MyComboBox::mouseReleaseEvent(QMouseEvent *e)
{
QStyleOptionComboBox opt;
this->initStyleOption(&opt);
// 此處是獲取滑鼠按下的座標對應的子控制元件
QStyle::SubControl sc = this->style()->hitTestComplexControl(QStyle::CC_ComboBox, &opt, e->pos(), this);
// 遮蔽右鍵
if (e->button() == Qt::RightButton) {
return;
}
if (property("Type") == "close") {
// 當sc == SC_ComboBoxArrow代表,按下的位置為下拉箭頭的位置
if (e->button() == Qt::LeftButton
&& sc == QStyle::SC_ComboBoxArrow) {
setCurrentIndex(-1);
} else {
QComboBox::showPopup();
}
return;
}
return QComboBox::mousePressEvent(e);
}
void MyComboBox::mousePressEvent(QMouseEvent *e)
{
// 此處為了禁止按住拖動時會展開下拉選單
Q_UNUSED(e);
return;
}
效果圖
程式碼下載
程式碼下載請看gitee MyComboBox