feat(vqt6): QCheckBox 改自绘子类(矢量框+对勾,按QPalette配色)
This commit is contained in:
1 parent
ceb601a2d3
commit
d9620ce43d
1 file changed
+62
-3
@@ -16,6 +16,9 @@
|
||||
#include <QPlainTextEdit>
|
||||
#include <QCheckBox>
|
||||
#include <QRadioButton>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QStyleOptionButton>
|
||||
#include <QComboBox>
|
||||
#include <QListWidget>
|
||||
#include <QProgressBar>
|
||||
@@ -847,18 +850,74 @@ extern "C" VQT6_API int vqt6_qplaintextedit_line_count(void* pte) {
|
||||
// ============================================================
|
||||
// QCheckBox / QRadioButton
|
||||
// ============================================================
|
||||
|
||||
// 自绘 QCheckBox:边框+矢量对勾都按 QPalette 绘制,
|
||||
// 避免浅色/深色主题切换时原生对勾或边框丢失
|
||||
class vqt6_CheckBox : public QCheckBox {
|
||||
public:
|
||||
vqt6_CheckBox(QWidget* parent = nullptr) : QCheckBox(parent) {}
|
||||
vqt6_CheckBox(const QString& text, QWidget* parent = nullptr) : QCheckBox(text, parent) {}
|
||||
|
||||
protected:
|
||||
void paintEvent(QPaintEvent*) override {
|
||||
QPainter p(this);
|
||||
p.setRenderHint(QPainter::Antialiasing, true);
|
||||
const QPalette& pal = palette();
|
||||
QStyleOptionButton opt;
|
||||
initStyleOption(&opt);
|
||||
QRect r = style()->subElementRect(QStyle::SE_CheckBoxIndicator, &opt, this);
|
||||
if (r.isEmpty() || r.isNull()) {
|
||||
r = QRect(0, 0, 16, 16);
|
||||
r.moveCenter(QPoint(rect().left() + 12, rect().center().y()));
|
||||
}
|
||||
QRectF box(r.left() + 1.0, r.top() + 1.0, r.width() - 2.0, r.height() - 2.0);
|
||||
if (box.width() < 10.0 || box.height() < 10.0) {
|
||||
box = QRectF(0, 0, 16, 16);
|
||||
box.moveCenter(QPointF(r.center().x(), r.center().y()));
|
||||
}
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(box, 3.0, 3.0);
|
||||
const bool on = isChecked();
|
||||
const bool en = isEnabled();
|
||||
QColor border = en ? pal.text().color() : pal.placeholderText().color();
|
||||
if (on) {
|
||||
p.fillPath(path, en ? pal.highlight() : pal.button());
|
||||
border = en ? pal.highlight().color() : pal.buttonText().color();
|
||||
} else {
|
||||
p.fillPath(path, en ? pal.base() : pal.window());
|
||||
}
|
||||
QPen bpen(border, 1.4);
|
||||
p.setPen(bpen);
|
||||
p.drawPath(path);
|
||||
if (on && en) {
|
||||
QPen cpen(pal.highlightedText(), 2.2);
|
||||
cpen.setCapStyle(Qt::RoundCap);
|
||||
p.setPen(cpen);
|
||||
const qreal x0 = box.left(), y0 = box.top(), w = box.width(), h = box.height();
|
||||
p.drawLine(QPointF(x0 + w * 0.24, y0 + h * 0.54), QPointF(x0 + w * 0.43, y0 + h * 0.73));
|
||||
p.drawLine(QPointF(x0 + w * 0.43, y0 + h * 0.73), QPointF(x0 + w * 0.78, y0 + h * 0.28));
|
||||
}
|
||||
// 文本
|
||||
QRect lr = style()->subElementRect(QStyle::SE_CheckBoxContents, &opt, this);
|
||||
if (!lr.isEmpty() && !lr.isNull()) {
|
||||
p.setPen(QPen(en ? pal.text() : pal.placeholderText(), 1.0));
|
||||
p.drawText(lr, Qt::AlignLeft | Qt::AlignVCenter, text());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
extern "C" VQT6_API void* vqt6_qcheckbox_create(void) {
|
||||
return new QCheckBox();
|
||||
return new vqt6_CheckBox();
|
||||
}
|
||||
|
||||
extern "C" VQT6_API void* vqt6_qcheckbox_create_with_text(void* text) {
|
||||
if (text == nullptr) return nullptr;
|
||||
return new QCheckBox(*static_cast<QString*>(text));
|
||||
return new vqt6_CheckBox(*static_cast<QString*>(text));
|
||||
}
|
||||
|
||||
extern "C" VQT6_API void* vqt6_qcheckbox_create_with_text_parent(void* text, void* parent) {
|
||||
if (text == nullptr || parent == nullptr) return nullptr;
|
||||
return new QCheckBox(*static_cast<QString*>(text), static_cast<QWidget*>(parent));
|
||||
return new vqt6_CheckBox(*static_cast<QString*>(text), static_cast<QWidget*>(parent));
|
||||
}
|
||||
|
||||
extern "C" VQT6_API void vqt6_qcheckbox_set_checked(void* cb, int checked) {
|
||||
|
||||
Reference in new issue
Block a user