将QGraphicsScene嵌入到QML中

时间:2017-03-10 09:14:43

标签: c++ qt qml

我正在和Qt一起打牌。最初,UI是使用Qt Widgets用C ++编写的,但在移植到Android之后(Qt Widgets应用程序看起来很笨拙,因为设置和颜色选择对话几乎无法使用)我决定切换到QML,保持游戏C ++中的逻辑。

然而,游戏逻辑中无法与视觉渲染分离的部分(例如玩家将牌放在桌面上)是用QGraphicsScene - 派生类编写的:

class Table : public QGraphicsScene
{
    // some code omitted
}

Table::Table(QObject* parent) : QGraphicsScene(parent) { /* ... */ }

我尝试通过TableqmlRegisterType()注册为QML类型,但它对我不起作用 - 将Table对象放入段落中的QML结果中在QGraphicsScene构造函数中。这是回溯的一部分:

#0  0x19312fa4 in std::__atomic_base<int>::load (__m=std::memory_order_relaxed, this=0xabababab) at C:/MINGW530/i686-w64-mingw32/include/c++/bits/atomic_base.h:396
        __b = std::memory_order_relaxed
#1  QAtomicOps<int>::load<int> (_q_value=...) at ../../include/QtCore/../../src/corelib/arch/qatomic_cxx11.h:227
No locals.
#2  0x193e1780 in QBasicAtomicInteger<int>::load (this=0xabababab) at ../../include/QtCore/../../src/corelib/thread/qbasicatomic.h:102
No locals.
#3  0x1940f7a7 in QtPrivate::RefCount::isShared (this=0xabababab) at ../../include/QtCore/../../src/corelib/tools/qrefcount.h:101
        count = 571316634
#4  0x1937f29d in QList<QGraphicsScene*>::append (this=0x139914c, t=@0x112e8cc: 0x362be1a8) at ../../include/QtCore/../../src/corelib/tools/qlist.h:580
No locals.
#5  0x192a1188 in QGraphicsScenePrivate::init (this=0x362be258) at graphicsview\qgraphicsscene.cpp:334
        q = 0x362be1a8
#6  0x192a61e9 in QGraphicsScene::QGraphicsScene (this=0x362be1a8, parent=0x0) at graphicsview\qgraphicsscene.cpp:1636
No locals.
#7  0x00402f53 in Table::Table (this=0x362be1a8, parent=0x0) at ..\OpenFool\src\table.cpp:41
No locals.
#8  0x0041239a in QQmlPrivate::QQmlElement<Table>::QQmlElement (this=0x362be1a8) at J:/Qt/Qt5.8.0/5.8/mingw53_32/include/QtQml/qqmlprivate.h:99
No locals.
#9  0x0041235d in QQmlPrivate::createInto<Table> (memory=0x362be1a8) at J:/Qt/Qt5.8.0/5.8/mingw53_32/include/QtQml/qqmlprivate.h:108
No locals.
#10 0x01c7a5d5 in QQmlType::create (this=0x1398550, out=0x112ed70, memory=0x112ed4c, additionalMemory=72) at qml\qqmlmetatype.cpp:761
        rv = 0x362be1a8 

那么,有没有办法重新使用Table的代码而无需将其重新编写为QML?

3 个答案:

答案 0 :(得分:2)

据我所知,QtWidget和QML的渲染引擎根本不同,因此很难将Widget注册为QML Type

所以我认为最适合你的两个选择是:

  1. 使其适应QML
  2. QQuickPaintedItem扩展为与QGraphicsScene具有最相似的API,以便您在代码中所需的更改很少。 (*谢谢你, @BenjaminT 指的是QQuickPaintedItem而不是Context2D

答案 1 :(得分:1)

您需要CURRENCIES_DIC = {'CN':'CHINA', 'US':'USA'} LOW_Q = 0.05 HIGH_Q = 0.95 # mark the data for respective country as outlier def calculate_outliers(df): df['country'] = df.port.str[:2].map(CURRENCIES_DIC) df['outlier'] = 0 for c in df.country.unique(): q = df.value[df.country==c].quantile([LOW_Q, HIGH_Q]) df.loc[df.index[df.country==c], 'outlier'] = (df.value[df.country==c].apply(lambda x: 1 if x<q[LOW_Q] or x>q[HIGH_Q] else 0)) return df 窗口小部件才能显示df[np.abs(df.Data-df.Data.mean())<=(3*df.Data.std())] #keep only the ones that are within +3 to -3 standard deviations in the column 'Data'.。 但是,您无法在Qt Quick 2界面中嵌入小部件。 (如果你使用Qt Quick 1,请参阅@xander回答)。

但如果你以相反的方式解决问题,那么就有一个解决方案。您可以制作Qt Widget HMI,在QGraphicsView小部件中显示您的场景,并使用一个或多个QQuickWidget显示您的Qt Quick部分。这有一些限制,但是如果你没有重叠QtQuick和QtWidget部分,那么效果很好并且非常有效

答案 2 :(得分:0)

据我所知,您无法在Qt Quick 2元素中嵌入QWidget,但是如果您可以使用Qt Quick 1,则仍然可以使用自定义QDeclarativeItem和{{1} }。

自定义QGraphicsProxyWidget的示例:

QPushButton

在您的情况下,您甚至可以直接用#include <QtDeclarative> #include <QtGui> class PushButtonItem : public QDeclarativeItem { Q_OBJECT public: PushButtonItem(QDeclarativeItem *parent =0) : QDeclarativeItem(parent) { pb = new QPushButton("text"); proxy = new QGraphicsProxyWidget(this); proxy->setWidget(pb); proxy->setPos(-pb->sizeHint().width()/2, -pb->sizeHint().height()/2); } private: QPushButton *pb; QGraphicsProxyWidget *proxy; }; #include "main.moc" int main(int argc, char **argv) { QApplication app(argc, argv); QDeclarativeView view; qmlRegisterType<PushButtonItem>("PushButton", 1, 0, "PushButtonItem"); view.setSource(QUrl::fromLocalFile("file.qml")); view.show(); return app.exec(); }; 替换QGraphicsProxyWidget因为QGraphicsScene是Qt Quick 1中的基类(在Qt Quick 2中已被替换)。