我写了一个自定义的Qt小部件,扩展了QWidget
类。
让我们考虑以下代码:
.h
#ifndef SS_TEST_H
#define SS_TEST_H
#include <QMainWindow>
class TestWidget : public QWidget
{
Q_OBJECT // ***>>> BUG HERE <<<***
public:
TestWidget(const QString & v1, const QString & v2, QWidget * parent = nullptr);
};
class TestWindow : public QMainWindow
{
Q_OBJECT
public:
TestWindow();
};
#endif // SS_TEST_H
.cpp
#include "ss_test.h"
#include <QGridLayout>
#include <QLabel>
#include <QApplication>
TestWidget::TestWidget(const QString & v1, const QString & v2, QWidget * parent) : QWidget(parent)
{
QGridLayout * lay = new QGridLayout;
QLabel * field = new QLabel(v1, this);
QLabel * value = new QLabel(v2, this);
value->setMinimumWidth(80);
value->setAlignment(Qt::AlignCenter);
value->setStyleSheet("QLabel { background-color: white; border: 1px solid silver; }");
lay->addWidget(field, 0, 0);
lay->addWidget(value, 0, 1);
this->setLayout(lay);
this->setStyleSheet("QWidget { background-color: red; }");
}
TestWindow::TestWindow()
{
setWindowTitle("ss test");
resize(400, 300);
QWidget * cw = new QWidget;
QVBoxLayout * cl = new QVBoxLayout;
TestWidget * tw1 = new TestWidget("Field 1", "Value 1", this);
TestWidget * tw2 = new TestWidget("Field 2", "Value 2", this);
cl->addWidget(tw1);
cl->addWidget(tw2);
cl->addStretch();
cw->setLayout(cl);
this->setCentralWidget(cw);
}
int main(int argc, char ** argv)
{
QApplication app(argc, argv);
TestWindow tw;
tw.show();
return app.exec();
}
我正在谈论的小部件是TestWidget
类。
在类声明中没有Q_OBJECT
宏,我得到的正是我想要的样式:
但是,如果我在类声明的开头添加了Q_OBJECT
宏(如您在头文件中看到的注释),它会意外地修改小部件的样式:
我不明白这里会发生什么。
当然,在我的真实项目中,此小部件比在此最小示例中要复杂得多,并且必然需要Q_OBJECT
宏(以便使用信号/插槽机制和qobject_cast
)
如果有人能向我解释Q_OBJECT
在这里的工作以及原因,我将不胜感激。
答案 0 :(得分:2)
必须仔细阅读文档才能偶然发现正确的passage。
您的TestWidget类需要重新实现paintEvent:
void TestWidget::paintEvent(QPaintEvent *)
{
QStyleOption opt;
opt.init(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
}
还有一个重要说明,您必须定义Q_OBJECT宏。
警告:请确保为自定义窗口小部件定义了Q_OBJECT宏。
我尝试过,这种行为似乎符合您的需求。
在缺少Q_OBJECT的情况下,这种奇怪行为的可能解释可能是qobject_cast<TestWidget*>(widget)
将产生nullptr
。这可能会导致呈现的样式表出现不同的行为。