Files
Renderive/Widget/component/Combo_Box.h
T
2026-08-01 20:09:45 +08:00

206 lines
10 KiB
C++

#pragma once
#include <QComboBox>
#include <qlistview.h>
#include "global.h"
#include "Psc_Cpp_Core/Base/global_include.h"
class Combo_Box : public QComboBox {
public:
Combo_Box() {
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 {
std::cout << Psc::enum_int_to_string<QStyleOption::OptionType>(option->type).value();
}
if (element == QStyle::PE_FrameFocusRect) {
// QProxyStyle::drawPrimitive(element, option, painter, widget);
}
else {
std::cout << "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 {
std::cout << "line_edit 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 {
std::cout << "line_edit 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 {
std::cout << "line_edit 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) {
// std::cout << "This is the dropdown arrow button area: " << ret;
}
else if (sc == SC_ComboBoxListBoxPopup) {
// std::cout << "This is the edit box area: " << ret;
}
else if (sc == QStyle::SC_ScrollBarSubLine) {
// std::cout << "QStyle::SC_ScrollBarSubLine: " << ret;
}
else if (sc == QStyle::SC_ScrollBarAddLine) {
// std::cout << "QStyle::SC_ScrollBarSubLine: " << ret;
}
else {
std::cout << "Other subcontrol: " << sc;
}
}
else {
std::cout << "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();
// std::cout << 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 icon_rect = QRect(rect.left() + 3, rect.top() + 3, 30, 30);
// QRect name_rect = QRect(icon_rect.right() + 5, rect.top() + 3, rect.width() - 80, 20);
// QRect circle = QRect(name_rect.right() + 5, name_rect.top(), 10, 10);
// QRect number_rect = QRect(name_rect.x(), name_rect.y() + 20, 100, 20);
// std::cout << icon_rect << name_rect << circle << number_rect;
// painter->drawEllipse(circle);
// painter->setPen(QPen(QColor(0, 0, 0)));
// painter->setFont(QFont("微软雅黑", 9, QFont::Bold));
// painter->drawText(name_rect, Qt::AlignLeft, name);
// painter->drawText(number_rect, Qt::AlignLeft, number);
// painter->drawPixmap(icon_rect, icon.pixmap(icon_rect.size()));
// painter->restore();
// } else
// {
// std::cout << "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;
};
};