實現效果:
實現combobox的下拉框區域與item區域分開做UI交互顯示。
支持4種實現效果,如下
效果一:
效果二:
效果三:
效果四:
實現邏輯:
ui由一個toolbutton和combobox上下組合成,重點在于combobox。
我設置了4種枚舉,ButtonWithComboBox對應效果一;OnlyButton對應效果四;OnlyComboBox對應效果三;OnlyComboBoxDepart對應效果二。
一、交互
自定義一個combobox,在鼠標事件中判斷鼠標處于哪個位置。將combobox分為2個部分,一個是item區,區域的獲取方法
QRect itemRect = style()->subControlRect(QStyle::CC_ComboBox, &opt,QStyle::SC_ComboBoxEditField);
一個是下拉按鈕區,獲取方法是
_arrowRect = style()->subControlRect(QStyle::CC_ComboBox, &opt,QStyle::SC_ComboBoxArrow, this);
并設置一個變量用來記錄按鈕所在位置,這里,使用了setProperty,設置了一個參數名inArrowRect。當鼠標在item區時,inArrowRect為“out”,當鼠標在下拉按鈕區時,inArrowRect為“in”,當鼠標離開combobox時,inArrowRect為“null”。在css樣式表里結合inArrowRect的值設置交互。
二、自定義下拉區
在這里,我需要設置combobox支持下拉顯示自定義界面,所以我設置了一個變量_isCustomized,用來判斷下拉后是否使用自定義界面,如果使用自定義界面,只需要調用setPopupWidget(QWidget *widget),將自定義界面傳入。
此外,設置了一個變量_isTogether,用來判斷是否要將combobox的Item區與下拉按鈕區分開顯示,如果設置為false,那么會按原始的樣式顯示,兩者是整體;設置為true,樣式就會使用我上面顯示的。
因為常用的是自定義Menu,所以我封裝了一個函數QAction* addMenuAciton(QObject *obj,QString name,QString iconName,const QString &toolTip = "",bool isCheckable = false),專門用來顯示自定義Menu。
此外,就是有時候下拉區域是圖片帶文字的,點擊后,最終只顯示圖片或文字。所以這里要注意,我寫的這個類,下拉區域的顯示和combobox最終顯示的是獨立設置的2個。combobox顯示的內容是通過comboBox的addItem來添加。通過設置一個變量_comboType來設置combobox顯示什么。
實現代碼:
具體代碼實現如下
.cpp
#ifndef TOOLCOMBOBOX_H
#define TOOLCOMBOBOX_H#include <QWidget>
#include <QComboBox>
#include <QMouseEvent>
#include <QPainter>
#include <QVBoxLayout>
#include <QAbstractItemView>
#include <QStandardItem>
#include <QStylePainter>
#include <QStyleOptionComboBox>namespace Ui {
class ToolComboBox;
}
namespace RO_xxx{class IndependentComboBox : public QComboBox {Q_OBJECT
public:enum comboShow{iconAndText =0,onlyText =1,onlyIcon=2};Q_ENUM(comboShow)using QComboBox::QComboBox;void setComboShow(comboShow type){_comboType = type;}void setPopupWidget(QWidget *widget){_customPopup = widget;_customPopup->setWindowFlag(Qt::Popup);// 設置為 Popup 類型// 確保 Popup 關閉時能正確觸發 hidePopup()connect(_customPopup, &QWidget::destroyed, this, &QComboBox::hidePopup);}void setTogether(bool together){_isTogether = together;}void setComboBoxPopCustomized(bool isCustomized){_isCusto