我正在和Qt一起打牌。最初,UI是使用Qt Widgets用C ++编写的,但在移植到Android之后(Qt Widgets应用程序看起来很笨拙,因为设置和颜色选择对话几乎无法使用)我决定切换到QML,保持游戏C ++中的逻辑。
然而,游戏逻辑中无法与视觉渲染分离的部分(例如玩家将牌放在桌面上)是用QGraphicsScene
- 派生类编写的:
class Table : public QGraphicsScene
{
// some code omitted
}
Table::Table(QObject* parent) : QGraphicsScene(parent) { /* ... */ }
我尝试通过Table
将qmlRegisterType()
注册为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?
答案 0 :(得分:2)
据我所知,QtWidget和QML的渲染引擎根本不同,因此很难将Widget
注册为QML Type
。
所以我认为最适合你的两个选择是:
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中已被替换)。