qml调用Qwidget控件
时间: 2023-10-06 09:07:49 浏览: 142
如果你想在 QML 中使用 QWidget 控件,可以使用 QQmlWidgetAdapter 类。这个类可以将 QWidget 封装为一个 QML 组件,从而可以在 QML 中使用。以下是一个示例:
```cpp
#include <QtWidgets/QWidget>
#include <QtQuick/QQuickItem>
#include <QtQuick/QQuickWindow>
#include <QtQml/QQmlEngine>
#include <QtQml/QQmlComponent>
#include <QtQml/QQmlProperty>
class QQmlWidgetAdapter : public QQuickItem
{
Q_OBJECT
Q_PROPERTY(QWidget* widget READ widget WRITE setWidget NOTIFY widgetChanged)
public:
QQmlWidgetAdapter(QQuickItem *parent = nullptr)
: QQuickItem(parent), mWidget(nullptr)
{
setFlag(ItemHasContents, true);
}
QWidget *widget() const { return mWidget; }
void setWidget(QWidget *widget)
{
if (mWidget == widget)
return;
mWidget = widget;
emit widgetChanged();
if (mWidget) {
mWidget->setParent(window());
mWidget->installEventFilter(this);
mWidget->show();
}
}
signals:
void widgetChanged();
protected:
QSGNode *updatePaintNode(QSGNode *node, UpdatePaintNodeData *)
{
if (!mWidget)
return nullptr;
QWindow *win = window();
if (!win)
return nullptr;
QWidget *nativeParent = win->handle() ? QWidget::find(win->handle()) : nullptr;
if (!nativeParent)
return nullptr;
QRectF rectF = boundingRect();
QRect rect(rectF.x(), rectF.y(), rectF.width(), rectF.height());
QRegion region = QRegion(rect.toPolygon());
if (node)
delete node;
QPlatformWindow *platformWindow = QGuiApplication::platformNativeInterface()->nativeResourceForWindow(QByteArrayLiteral("window"), win);
QPlatformWindow *platformParent = nativeParent->windowHandle()->platformWindow();
QPlatformWindow *platformWidget = mWidget->windowHandle()->platformWindow();
QPlatformWindow *previousWindow = platformWidget->parent();
if (previousWindow && previousWindow != platformParent)
previousWindow->setParent(nullptr);
platformWidget->setParent(platformParent);
platformWidget->setGeometry(rect.toRect());
if (platformWindow->hasCapability(QPlatformWindow::AlwaysBuffered))
platformWidget->setWindowState(platformWidget->windowState() | Qt::WindowBuffered);
return new QSGPlatformWindow(platformWidget);
}
bool eventFilter(QObject *watched, QEvent *event)
{
if (watched == mWidget && event->type() == QEvent::Resize) {
update();
return true;
}
return false;
}
private:
QWidget *mWidget;
};
```
在 QML 中使用这个类,可以将 QWidget 封装为一个 QML 组件:
```qml
import QtQuick 2.0
Item {
width: 400
height: 300
QQmlWidgetAdapter {
anchors.fill: parent
widget: myQWidget
}
QWidget {
id: myQWidget
objectName: "myQWidget"
// 设置 QWidget 的属性
}
}
```
这个例子中,我们首先创建了一个 QQmlWidgetAdapter 类,它继承自 QQuickItem。在这个类中,我们定义了一个 widget 属性,它是一个指向 QWidget 的指针。在 setWidget 函数中,我们将 QWidget 的父窗口设置为 QML 窗口,并安装一个事件过滤器。在 updatePaintNode 函数中,我们创建一个 QSGPlatformWindow,将 QWidget 放到这个窗口中,并返回这个窗口的 QSGNode。在 eventFilter 函数中,我们监听 QWidget 的大小变化,以便在大小变化时更新 QML 界面。在 QML 中,我们使用 QQmlWidgetAdapter 将 QWidget 封装为一个 QML 组件,然后将这个组件作为子项放到父项中。注意,我们必须给这个 QWidget 设置一个 id,以便在 QML 中引用它。
阅读全文