Как объявить Qt::PenStyle в Qt5?

Я переношу проект с Qt 4.x на 5, и есть класс, содержащий атрибут, который идет:

Qt::PenStyle penStyle;

и его соответствующая функция получения:

Qt::PenStyle getPenStyle() {return penStyle;}

Я получаю ошибку компиляции, говорящую, что

error: 'QVariant::QVariant(Qt::PenStyle)' is private
     QVariant(Qt::PenStyle) Q_DECL_EQ_DELETE;
     ^
..\marssies\painterbar.cpp:217:88: error: within this context
         lineStyle -> setCurrentIndex(lineStyle -> findData(graphicObject->getPenStyle()));
                                                                                        ^

Проведя некоторое исследование, я нашел это:

QVariant:
*Inconsistent constructor taking Qt::GlobalColor and producing QVariant(QColor) instance was removed. Code constructing such variants can be migrated by explicitly calling QColor constructor. For example from “QVariant(Qt::red)” to “QVariant(QColor(Qt::red))

*Similarly, implicit creation of QVariants from enum values Qt::BrushStyle, Qt::PenStyle, and Qt::CursorShape have been removed. Create objects explicitly or use static_cast(Qt::SolidLine) to create a QVariant of type int with the same value as the enum.

Вопрос в том, как мне объявить атрибут/функцию, если я не могу сделать Qt::PenStyle просто так? Что означает явное создание объектов? Я пытался сделать что-то, как говорится в цитате, но мне не удалось решить эту проблему. Мне удалось решить другие подобные ошибки, но ни одна из них не была декларацией атрибутов или функций.

Полная ошибка:

In file included from ..\..\..\..\..\Qt5\5.2.1\mingw48_32\include\QtCore/qsettings.h:46:0,
                 from ..\..\..\..\..\Qt5\5.2.1\mingw48_32\include\QtCore/QSettings:1,
                 from ..\marssies\appcommon.h:10,
                 from ..\marssies\painterbar.h:5,
                 from ..\marssies\painterbar.cpp:1:
..\..\..\..\..\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h: In member function 'void PainterBar::setGraphicObject(GraphicsPrimitive*, PainterBar::FinishMode)':
..\..\..\..\..\Qt5\5.2.1\mingw48_32\include/QtCore/qvariant.h:482:5: error: 'QVariant::QVariant(Qt::PenStyle)' is private
     QVariant(Qt::PenStyle) Q_DECL_EQ_DELETE;
     ^
..\marssies\painterbar.cpp:217:88: error: within this context
         lineStyle -> setCurrentIndex(lineStyle -> findData(graphicObject->getPenStyle()));
                                                                                        ^

person Victor    schedule 24.04.2014    source источник


Ответы (1)


Проблема в том, что перечисления - это немного сложный тип, и Qt 5, похоже, убрал некоторую специфическую магию для этих рассматриваемых перечислений. Конструктор базового шаблона для QVariant определен как частный, чтобы гарантировать, что QVariant могут быть созданы только с типами, с которыми они действительно могут работать.

Первое решение, предложенное в документах, заключается в создании экземпляра объекта, потому что в QVariant легче хранить «нормальный» тип, чем в перечислении. QColor, QPen и т. д. - все это QObject, поэтому для них работает общая логика их хранения в QVariant; это не работает для Qt::PenStyle.

Второе решение — это типичное решение в стиле C, которое люди используют при работе с перечислениями. Поскольку перечисление хранится как целое число, вы всегда можете явно привести к типу int (и C иногда также делает это неявно, а C ++, на самом деле, не делает). То, что эффективно хранится в QVariant, — это int, и только вы, программист, знаете, что на самом деле это Qt::PenStyle.

Хотя первое решение немного менее эффективно (думая о хранении тысяч объектов QPen вместо QPenStyles/ints), оно может быть более чистым, поскольку сохраняется семантика (QVariant содержит перо, которым можно рисовать).

Если это не работает для вас:

int getPenStyle() {return (int)penStyle;}

or

QPen getPenStyle() {return QPen(penStyle);}

тогда, пожалуйста, опубликуйте автономный пример, чтобы мы могли продолжить обсуждение.

person ypnos    schedule 24.04.2014