Files
Renderive/YSGraphic_Core/component/ComboBox.h
T
2026-06-16 13:33:27 +08:00

216 lines
10 KiB
C++

#pragma once
#include <QComboBox>
#include "global.h"
class ComboBox : public QComboBox {
public:
ComboBox() {
setStyle(new Style());
setView(new view());
setItemDelegate(new comboboxdelegate());
QWidget* container = this->findChild<QFrame*>();
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<const QComboBox*>(widget);
if (!t) return;
if (option->type == QStyleOption::SO_FocusRect)
{
const QStyleOptionComboBox* opt = qstyleoption_cast<const QStyleOptionComboBox*>(option);
// QProxyStyle::drawPrimitive(element, option, painter, widget);
} else
{
qDebug() << QString::fromStdString(enum_int_to_string<QStyleOption::OptionType>(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<const QComboBox*>(widget);
if (!t) return;
auto opt = qstyleoption_cast<const QStyleOptionComboBox*>(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<const QComboBox*>(widget);
if (!t) return;
auto opt = qstyleoption_cast<const QStyleOptionComboBox*>(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<const QComboBox*>(widget);
if (!t) return QProxyStyle::subElementRect(element, option, widget);
auto opt = qstyleoption_cast<const QStyleOptionComboBox*>(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<const QStyleOptionComboBox*>(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<QIcon>();
// 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;
};
};