实现效果:
实现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