hyperk-021
2025-06-05 8c679ef19e9d5c33947cdf1cc1e5550e3d442308
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
#include "customdelegate.h"
 
namespace Ripples {
 
CustomButtonDelegate::CustomButtonDelegate(const QStringList& iconPathList, QObject *parent):
    m_iconPathList(iconPathList),
    QStyledItemDelegate(parent)
{}
 
void CustomButtonDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    if (index.column() == 3 || index.column() == 4 || index.column() == 5 || index.column() == 6 || index.column() == 7){
 
        QStyleOptionButton button;
        button.rect = option.rect;
        button.state = QStyle::State_Enabled;
 
        // 获取Icon路径
        QIcon icon = QIcon(m_iconPathList.at(index.column()-3));
 
        const bool isHovered = (hoveredIndex == index);
        const bool isPressed = (pressedIndex == index);
 
        if(isPressed)
            button.state |= QStyle::State_Sunken;
        else if(isHovered)
            button.state |= QStyle::State_MouseOver;
        else
            button.state |= QStyle::State_Raised;
 
 
        // 图标绘制区域
        int iconSize = qMin(option.rect.width(), option.rect.height()) - 6;
        QRect iconRect(
            option.rect.center().x() - iconSize / 2,
            option.rect.center().y() - iconSize / 2,
            iconSize, iconSize
            );
 
        // 按下时偏移图标
        if (pressedIndex == index)
            iconRect.translate(1, 1);  // 向右下偏移1像素
 
        // 绘制图标
        icon.paint(painter, iconRect, Qt::AlignCenter, QIcon::Normal);
    }
    else if (index.column() == 1){
        painter->save();
        // 获取数据
        QString topText = index.data(Qt::UserRole+1).toString();
        QString bottomText = index.data(Qt::UserRole+2).toString();
 
        QRect rect = option.rect;
 
        // 设置字体
        QFont topFont = option.font;
        topFont.setPointSize(topFont.pointSize() + 2);  // 更大字号
        QFont bottomFont = option.font;
        bottomFont.setPointSize(bottomFont.pointSize() - 1);  // 更小字号
 
        // 分割区域:上半部分和下半部分
        QRect topRect = rect.adjusted(4, 2, -4, -rect.height() / 2);
        QRect bottomRect = rect.adjusted(4, rect.height() / 2, -4, -2);
 
        // 绘制 topText
        painter->setFont(topFont);
        painter->drawText(topRect, Qt::AlignLeft | Qt::AlignVCenter, topText);
 
        // 绘制 bottomText
        painter->setFont(bottomFont);
        painter->setPen(Qt::gray);
        painter->drawText(bottomRect, Qt::AlignLeft | Qt::AlignVCenter, bottomText);
        painter->restore();
 
    }
    else{
 
        QStyledItemDelegate::paint(painter, option, index);
    }
}
 
bool CustomButtonDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
    if (index.column() == 3 || index.column() == 4 || index.column() == 5 || index.column() == 6 || index.column() == 7){
        auto *mouseEvent = dynamic_cast<QMouseEvent *>(event);
        if (!mouseEvent)
            return false;
 
        bool inside = option.rect.contains(mouseEvent->pos());
 
        switch (event->type()) {
        case QEvent::MouseMove:
            if (inside) hoveredIndex = index;
            else if (hoveredIndex == index) hoveredIndex = QModelIndex();
            requestUpdate(option, index);
            break;
 
        case QEvent::MouseButtonPress:
            if (inside) {
                pressedIndex = index;
                requestUpdate(option, index);
            }
            break;
 
        case QEvent::MouseButtonRelease:
            if (pressedIndex == index && inside)
                emit iconClicked(index);
            pressedIndex = QModelIndex();
            requestUpdate(option, index);
            break;
 
        default:
            break;
        }
    }
    return true;
}
 
QSize CustomButtonDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    // 根据字体估算高度
    QFontMetrics topFM(option.font);
    QFontMetrics bottomFM(option.font);
    int height = topFM.height() + bottomFM.height() + 6;  // 加一些padding
    return QSize(100, height);
}
 
void CustomButtonDelegate::requestUpdate(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    auto *view = qobject_cast<QAbstractItemView *>(parent());
    if (view) {
        QRect rect = view->visualRect(index);
        view->viewport()->update(rect);
    }
}
 
 
 
} // namespace Ripples