Макрос Qt Q_OBJECT вызывает неожиданное поведение с таблицами стилей - PullRequest
2 голосов
/ 10 июля 2019

Я написал собственный виджет 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 в объявлении класса я получаю именно тот стиль, который мне нужен: enter image description here

Но если я добавлю макрос Q_OBJECT в начале объявления класса (как вы можете видеть комментарии в заголовочном файле), он неожиданно изменит стиль виджета: enter image description here

Я не понимаю, что здесь происходит.

Конечно, в моем реальном проекте виджет гораздо более детально проработан, чем в этом минимальном примере, и для него обязательно требуется макрос Q_OBJECT (для использования механизмов сигнала / слотов и qobject_cast).

Я был бы очень признателен, если бы кто-нибудь мог объяснить мне, что Q_OBJECT делает здесь и почему.

1 Ответ

2 голосов
/ 10 июля 2019

Нужно внимательно прочитать документацию, чтобы наткнуться на правый проход .

Ваш класс 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.Это может привести к другому поведению отображаемой таблицы стилей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...