首页 > 解决方案 > QML将窗口设置为另一个窗口,后面有对象

问题描述

我在 Windows 10 上使用 Qt5.12.0,我想看看是否可以在我的 rootObject qml 应用程序窗口中设置一个 qml 窗口并在这个子窗口前面绘制。

这是我的实际代码。

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    color: "transparent"
}

主文件

#include <QApplication>
#include <QQmlApplicationEngine>

#include "video.h"

#include <QQuickWindow>
#include <QUrl>

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

    QApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;


    QQuickWindow* window;
    window = qobject_cast<QQuickWindow*>(engine.rootObjects().at(0));

    CVideo *_pVideo = new CVideo();
    _pVideo->init(&engine, window);

    return app.exec();
}

视频.h

#ifndef VIDEO_H
#define VIDEO_H

#include <QQmlApplicationEngine>
#include <QQuickWindow>

class CVideo
{
public:
    CVideo() = default;
    void init(QQmlApplicationEngine* _engine, QQuickWindow* _pWindow);
};

#endif

视频.cpp

#include "video.h"

#include <gst/gst.h>
#include <gst/video/videooverlay.h>

#include <QQmlComponent>
#include <QQuickItem>
#include <QQuickWindow>

void CVideo::init(QQmlApplicationEngine* _engine, QQuickWindow* _pWindow)
{
    gst_init(nullptr, nullptr);
    GstElement *pipeline =
           gst_parse_launch
           (
                "rtspsrc location=rtsp://192.168.1.168:554/hdmi latency=50 ! application/x-rtp,media=(string)video ! decodebin ! glimagesink",
           nullptr);
    GstElement *sink  =  gst_bin_get_by_name(GST_BIN(pipeline), "sink");


    WId xwinid = -1;
    QQmlComponent *_pComponent = new QQmlComponent(_engine, QUrl(QStringLiteral("QML/VideoItem.qml")), _pWindow);
    QQuickItem* _pVideoItem = qobject_cast<QQuickItem*>(_pComponent->create());
    _pVideoItem->setParent(_pWindow);

    _pVideoItem->setParentItem(_pWindow->contentItem());
    _pVideoItem->setProperty("id", "_videoOutput");
    QObject *_pRootObject = dynamic_cast<QObject*>(_engine->rootObjects().first());
    QList<QWindow*> _allWindow = _pRootObject->findChildren<QWindow*>();
    QWindow *_window = _allWindow.first();
    xwinid = _window->winId();
    gst_video_overlay_set_window_handle (GST_VIDEO_OVERLAY (sink), xwinid);
    _window->setParent(_pWindow);

    GstStateChangeReturn sret = gst_element_set_state (pipeline,
       GST_STATE_PLAYING);
    if (sret == GST_STATE_CHANGE_FAILURE) {
     gst_element_set_state (pipeline, GST_STATE_NULL);
     gst_object_unref (pipeline);
    }
}

视频项.qml

import QtQuick 2.0
import QtQuick.Window 2.3
import QtQuick.Controls 2.4

Item{
    id: _video
    x: 0
    y: 0
    width: 1280
    height: 800
    visible: true

    Window{
        id: _videoOutput
        visible: true
        x: 100
        y: 100
        width: 800
        height: 600
    }

    Button{
        id: _button
        x: 10
        y: 10
        width: 100
        height: 100
        text: "test"
    }
}

使用此代码,我看到 gstreamer (1.14.4) 读取了我的视频,但我的按钮位于视频下方,所以我希望它在它前面。

可以在我的视频项目前绘制 qml 项目(标签、按钮、图像...)吗?提前感谢您的回复。

标签: c++qtvideoqmlwindow

解决方案


推荐阅读