由于我項目開始使用Widgets,換公司后直接使用QML開發,沒有了解過如何實現widget到qml過渡,恰逢面試時遇到一家公司希望從widget遷移到qml開發,詢問相關實現,一時語塞,很尷尬,粗略研究并總結下。
對qwidget嵌入qml的操作,qt提供了兩種方式,(1) QQuickView 和 QWidget::createWindowContainer ()結合使用,但存在堆棧限制問題被放棄;(2) QQuickWidget,但是使用該種方式也存在如下問題需要注意;
對于qquickwidget,qt官方也提供了相應例子quickwidget,簡單如下所示。
// main.cpp
MainWindow::MainWindow(): m_quickWidget(new QQuickWidget)
{
...QUrl source("qrc:quickwidget/rotatingsquare.qml");connect(m_quickWidget, &QQuickWidget::statusChanged,this, &MainWindow::quickWidgetStatusChanged);connect(m_quickWidget, &QQuickWidget::sceneGraphError,this, &MainWindow::sceneGraphError);m_quickWidget->resize(300,300);m_quickWidget->setResizeMode(QQuickWidget::SizeRootObjectToView );m_quickWidget->setSource(source);centralWidget->addSubWindow(m_quickWidget);...}
void MainWindow::quickWidgetStatusChanged(QQuickWidget::Status status)
{if (status == QQuickWidget::Error) {QStringList errors;const auto widgetErrors = m_quickWidget->errors();for (const QQmlError &error : widgetErrors)errors.append(error.toString());}
}
void MainWindow::grabToImage()
{QFileDialog fd(this);fd.setAcceptMode(QFileDialog::AcceptSave);fd.setDefaultSuffix("png");fd.selectFile("test_grabToImage.png");if (fd.exec() == QDialog::Accepted) {// 這里C++層使用invokeMethod調用rotatingsquare.qml中performLayerBasedGrab函數QMetaObject::invokeMethod(m_quickWidget->rootObject(), "performLayerBasedGrab",Q_ARG(QVariant, fd.selectedFiles().first()));}
}
// rotatingsquare.qmlfunction performLayerBasedGrab(fn) {// rectangle的grabToImage函數root.grabToImage(function(result) {result.saveToFile(fn);});}
對于網上反應的某些信號獲取不到,測試后沒發現問題,不知道是不是版本問題,我測試版本為Qt5.12.12
https://blog.csdn.net/u011283226/article/details/117398629