QWidget 和 QML窗口 相互嵌套

  • QWidget界面和QML窗口相互嵌套都是需要借助 quickwidgets 这个模块中的类
  • 我这里使用的是QQuickWidget,这个类是继承QWidget的,就和 QWidget 一样使用就行
  • 使用布局控制 控件 的位置

1. C++代码

#include <QApplication>
#include <QtQuickWidgets/QQuickWidget>
#include <QQuickView>
#include <QHBoxLayout>
#include <QLabel>

int main(int argc, char *argv[])
{
	// QApplication::setAttribute(Qt::AA_UseSoftwareOpenGL);
	QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
	
	QApplication app(argc, argv);
	
	QWidget * widget = new QWidget;
	widget->setWindowTitle("widget 主窗口");
	widget->resize(800, 400);
	
	// 设置布局
	QHBoxLayout * layout = new QHBoxLayout;
	layout->setContentsMargins(0, 0, 0 ,0);
	widget->setLayout(layout);
	
	// qml 界面 嵌入到 widget
	QQuickWidget qmlWidget(QUrl("qrc:/main.qml"));
	qmlWidget.setResizeMode(QQuickWidget::SizeRootObjectToView );
	// 设置这个之后 anchor不用设置,root节点大小会根据 QQuickWidget大小改变
	// 在qml里 通过 parent 获取不到 widget 窗口 !!!	
	layout->addWidget(&qmlWidget);
	
	// widget 界面 嵌入到 qmlWidget里
	QLabel label("QLabel", &qmlWidget);
	label.move(100, 100);
	label.show();
	
	// widget 界面 嵌入到 widget
	QLabel nativeWidget;
	nativeWidget.setText("Widget");
	nativeWidget.setAlignment(Qt::AlignCenter);
	layout->addWidget(&nativeWidget);
	
	widget->show();
	
	return app.exec();
}

2. QML代码

  • 这个QML代码就随便写了一个简单的 Rectangle
  • 注意:如果是用 QQuickView或者QQuickWidget 加载的qml,root节点不能是 Window 这一类类型,最好是Rectangle
import QtQuick 2.9

Rectangle {
	//visible: true
	//width: 150
	//height: 150
	//anchors.fill: parent
	//anchors.centerIn: parent
	
	border.color: "#00ffd5"
	border.width: 10
	radius : 10
	
	Text {
		id : text
		anchors.centerIn: parent
		text: qsTr("QML Text")
		antialiasing: true	//抗锯齿
	}

	// 旋转动画
	NumberAnimation {
		id : numberAnimation
		target: text
		property: "rotation"
		from: 0
		to: 360
		duration: 3000
		
		running: true
		loops: Animation.Infinite
		
	}
}

3. 运行效果

  • 还有一点,Rectangle里不能放QWidget界面,否则直接断言退出程序
  • ASSERT: "!d->isWidget" in file [kernel\qobject.cpp, line 1979](kernel\qobject.cpp, line 1979)