#pragma once #include #include "global.h" class ComboBox : public QComboBox { public: ComboBox() { setStyle(new Style()); setView(new view()); setItemDelegate(new comboboxdelegate()); QWidget* container = this->findChild(); if (container) { container->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint); container->setAttribute(Qt::WA_TranslucentBackground); } } class Style : public QProxyStyle { public: void drawPrimitive(QStyle::PrimitiveElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override { // 先调用默认的绘制 auto t = qobject_cast(widget); if (!t) return; if (option->type == QStyleOption::SO_FocusRect) { const QStyleOptionComboBox* opt = qstyleoption_cast(option); // QProxyStyle::drawPrimitive(element, option, painter, widget); } else { qDebug() << QString::fromStdString(enum_int_to_string(option->type).value()); } if (element == QStyle::PE_FrameFocusRect) { // QProxyStyle::drawPrimitive(element, option, painter, widget); } else { qDebug() << "drawPrimitive == " << element; } } void drawComplexControl(ComplexControl control, const QStyleOptionComplex* option, QPainter* painter, const QWidget* widget) const override { auto t = qobject_cast(widget); if (!t) return; auto opt = qstyleoption_cast(option); // 控制当前选项外部的边框 if (control == QStyle::CC_ComboBox) { QPen pen; painter->setPen(pen); painter->drawRoundedRect(widget->rect().adjusted(0, 0, -1, -2), 4, 4); // QProxyStyle::drawComplexControl(control, option, painter, widget); } else { qDebug() << "lineEdit drawComplexControl " << control; } } void drawControl(ControlElement element, const QStyleOption* option, QPainter* painter, const QWidget* widget) const override { auto t = qobject_cast(widget); if (!t) return; auto opt = qstyleoption_cast(option); // 当前选择的选项 if (element == QStyle::CE_ComboBoxLabel) { QProxyStyle::drawControl(element, option, painter, widget); } else { qDebug() << "lineEdit drawControl " << element; } } QRect subElementRect(SubElement element, const QStyleOption* option, const QWidget* widget) const override { auto t = qobject_cast(widget); if (!t) return QProxyStyle::subElementRect(element, option, widget); auto opt = qstyleoption_cast(option); QRect ret = QProxyStyle::subElementRect(element, option, widget); // 这里可以自定义返回不同的 QRect 以控制子元素的大小或位置 if (element == QStyle::SE_ComboBoxLayoutItem) { // rect.adjust(5, 5, -5, -5); // 例如,让文本内容区域缩小一点 // return rect.adjusted(5, 5, -5, -5); return ret; } else { qDebug() << "lineEdit subElementRect " << element; } return ret; } QRect subControlRect(ComplexControl cc, const QStyleOptionComplex* option, SubControl sc, const QWidget* widget) const override { auto ret = QProxyStyle::subControlRect(cc, option, sc, widget); auto opt = qstyleoption_cast(option); if (cc == QStyle::CC_ComboBox) { if (sc == SC_ComboBoxArrow) { // qDebug() << "This is the dropdown arrow button area: " << ret; } else if (sc == SC_ComboBoxListBoxPopup) { // qDebug() << "This is the edit box area: " << ret; } else if (sc == QStyle::SC_ScrollBarSubLine) { // qDebug() << "QStyle::SC_ScrollBarSubLine: " << ret; } else if (sc == QStyle::SC_ScrollBarAddLine) { // qDebug() << "QStyle::SC_ScrollBarSubLine: " << ret; } else { qDebug() << "Other subcontrol: " << sc; } } else { qDebug() << "QRect subControlRect ??????? : " << sc; } return ret; } }; class view : public QListView { public: view(QWidget* parent = nullptr) : QListView(parent) { // 构造函数内容 } [[nodiscard]] QSize viewportSizeHint() const override{ return QListView::viewportSizeHint(); } protected: void paintEvent(QPaintEvent* e) override { QPainter painter(this->viewport()); auto s = this->viewport()->objectName(); // 绘制背景色 // painter.setBrush(Qt::blue); // painter.drawRoundedRect(rect(), 4, 4); // 使用白色填充整个视图区域 // 调用基类的 paintEvent 以确保默认绘制行为 QListView::paintEvent(e); } }; class comboboxdelegate : public QStyledItemDelegate { public: explicit comboboxdelegate(QObject* parent = nullptr) : QStyledItemDelegate(parent) {} ~comboboxdelegate() {} void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const override { QStyledItemDelegate::paint(painter, option, index); // if (index.isValid()) // { // painter->save(); // QString name = index.data(Qt::DisplayRole).toString(); // QVariant icondata = index.data(Qt::DecorationRole); // QIcon icon = icondata.value(); // QString number = index.data(Qt::UserRole).toString(); // bool isonline = index.data(Qt::UserRole + 1).toBool(); // qDebug() << name << number << isonline; // QRectF rect; // rect.setX(option.rect.x()); // rect.setY(option.rect.y()); // rect.setWidth(option.rect.width() - 1); // rect.setHeight(option.rect.height() - 1); // QPainterPath path; // path.moveTo(rect.topRight() - QPointF(radius, 0)); // path.lineTo(rect.topLeft() + QPointF(radius, 0)); // path.quadTo(rect.topLeft(), rect.topLeft() + QPointF(0, radius)); // path.lineTo(rect.bottomLeft() + QPointF(0, -radius)); // path.quadTo(rect.bottomLeft(), rect.bottomLeft() + QPointF(radius, 0)); // path.lineTo(rect.bottomRight() - QPointF(radius, 0)); // path.quadTo(rect.bottomRight(), rect.bottomRight() + QPointF(0, -radius)); // path.lineTo(rect.topRight() + QPointF(0, radius)); // path.quadTo(rect.topRight(), rect.topRight() + QPointF(-radius, -0)); // if (option.state.testFlag(QStyle::State_Selected)) // { // painter->setPen(QPen(Qt::blue)); // painter->setBrush(QColor(0, 255, 127)); // painter->drawPath(path); // } else if (option.state.testFlag(QStyle::State_Raised)) // { // painter->setPen(QPen(Qt::green)); // painter->setBrush(QColor(0, 127, 255)); // painter->drawPath(path); // } else // { // painter->setPen(QPen(Qt::gray)); // painter->setBrush(QColor(255, 255, 255)); // painter->drawPath(path); // } // QRect iconRect = QRect(rect.left() + 3, rect.top() + 3, 30, 30); // QRect nameRect = QRect(iconRect.right() + 5, rect.top() + 3, rect.width() - 80, 20); // QRect circle = QRect(nameRect.right() + 5, nameRect.top(), 10, 10); // QRect numberRect = QRect(nameRect.x(), nameRect.y() + 20, 100, 20); // qDebug() << iconRect << nameRect << circle << numberRect; // painter->drawEllipse(circle); // painter->setPen(QPen(QColor(0, 0, 0))); // painter->setFont(QFont("微软雅黑", 9, QFont::Bold)); // painter->drawText(nameRect, Qt::AlignLeft, name); // painter->drawText(numberRect, Qt::AlignLeft, number); // painter->drawPixmap(iconRect, icon.pixmap(iconRect.size())); // painter->restore(); // } else // { // qDebug() << "index is vaild?"; // } } [[nodiscard]] QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const override { Q_UNUSED(option) Q_UNUSED(index) return QStyledItemDelegate::sizeHint(option, index); } private: qreal radius = 8; }; };