216 lines
10 KiB
C++
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;
|
|
};
|
|
};
|