共享库中的 QQuickWindow 在 QApplication 中显示时自动关闭

Posted

技术标签:

【中文标题】共享库中的 QQuickWindow 在 QApplication 中显示时自动关闭【英文标题】:QQuickWindow in shared lib auto close when show in QApplication 【发布时间】:2019-04-26 09:45:44 【问题描述】:

我用 qt 开发了一个通用接口库。当我用触摸屏单击时,QPushbutton 上的按下效果出现问题(此效果在 10 次单击时出现一次)。

所以我用一个按钮创建了一个基本的 qml 应用程序,并且一直出现按下效果。我将 qml 部分包含到我的库中并将其加载到 QQuickWidget 中,并且我在按下效果时遇到了同样的问题。

所以我只想使用 qml。我的主要应用程序是一个 QApplication,我在其中加载我的库,在其中我使用 QQmlApplication Engine 加载 qml 文件。然后我通过 QQuickWindow 展示它。

当我启动我的应用程序时,我看到窗口打开了,但它会自动关闭。我认为我的 QApplication 没有检测到 QML,并且渲染器循环没有启动。

我在使用 QT5.5.1(MSVC2013,32 位)的 Windows 上

主应用程序的pro文件

QT += core xml widgets qml quick

TARGET = COM_INT
CONFIG += console
CONFIG -= app_bundle

TEMPLATE = app


SOURCES += main.cpp \
    comint.cpp
HEADERS += \
    comint.h \

INCLUDEPATH += "$$(My_Workspace)/Modules_Generique/IHM_Soft"
Release
    LIBS += "$$(My_Workspace_build)/IHM_Soft/release/IHM_Soft.lib"


Debug
    LIBS += "$$(My_Workspace_build)/IHM_Soft/debug/IHM_Soft.lib"

主应用程序(exe)main.cpp

#include <QApplication>
#include <QQmlApplicationEngine>

#include "comint.h"

int main(int argc, char *argv[])

    QApplication a(argc, argv);

    ComInt com;
    com.initialize();

    return a.exec();

ComInt 类: 源文件comint.cpp

#include "comint.h"
#include "ihmsoft.h"

ComInt::ComInt()



void ComInt::initialize()

    this->m_pIHMSoft = new IHMSoft();

头文件comint.h

#ifndef COMINT_H
#define COMINT_H

class IHMSoft;

class ComInt

public:
    ComInt();
    void initialize();
private:
    IHMSoft *m_pIHMSoft;
;

#endif // COMINT_H

共享库的pro文件

QT       += xml widgets core qml quick quickwidgets
CONFIG  += c++11

TARGET = IHM_Soft
TEMPLATE = lib

DEFINES += IHM_SOFT_LIBRARY

SOURCES +=  ihmsoft.cpp
HEADERS +=  ihmsoft.h\
        ihm_soft_global.h

RESOURCES += \
    rsc.qrc

共享库:源文件 ihm_soft.cpp

#include "ihmsoft.h"
#include <QQmlApplicationEngine>
#include <QQuickWindow>

IHMSoft::IHMSoft()

    qputenv("QT_QUICK_CONTROLS_STYLE", "Base");
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/IHM_Soft.qml")));
    QList<QObject*> root = engine.rootObjects();
    QQuickWindow *window = qobject_cast<QQuickWindow*>(root.at(0));
    window->show();

头文件 ihm_soft.h

#ifndef IHM_SOFT_H
#define IHM_SOFT_H

#include "ihm_soft_global.h"

class IHM_SOFT_SHARED_EXPORT IHM_Soft


public:
    IHM_Soft();
;

#endif // IHM_SOFT_H

全局文件 ihm_soft_global.h

#ifndef IHM_SOFT_GLOBAL_H
#define IHM_SOFT_GLOBAL_H

#include <QtCore/qglobal.h>

#if defined(IHM_SOFT_LIBRARY)
#  define IHM_SOFT_SHARED_EXPORT Q_DECL_EXPORT
#else
#  define IHM_SOFT_SHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // IHM_SOFT_GLOBAL_H

Qml 文件

import QtQuick 2.0
import QtQuick.Controls 1.4

import QtQuick.Window 2.0



ApplicationWindow 
    visible: true
    width: 500
    height: 500

    Button 
        visible: true
        iconSource: "resources/t_on_off.png"
    

编辑:抱歉,主应用程序的代码是一个不包含 lib 的测试应用程序。

【问题讨论】:

提供一个minimal reproducible example,如何加载lib? main 中的代码与 lib 有何关系?无论如何,我看到了 2 个不应该发生的 QQmlApplicationEngine 实例 我有一些代码可以测试问题。 【参考方案1】:

一个变量在其作用域结束时被删除,在您的情况下,引擎是一个局部变量,在 IHMSoft 完成构建时被删除,因此您会看到窗口关闭。解决方案是让它成为类的成员:

*.h

#ifndef IHM_SOFT_H
#define IHM_SOFT_H

#include "ihm_soft_global.h"
#include <QQmlApplicationEngine>

class IHM_SOFT_SHARED_EXPORT IHM_Soft


public:
    IHM_Soft();
private:
    QQmlApplicationEngine engine; // member
;

#endif // IHM_SOFT_H

*.cpp

#include "ihmsoft.h"

IHMSoft::IHMSoft()
    qputenv("QT_QUICK_CONTROLS_STYLE", "Base");
    engine.load(QUrl(QStringLiteral("qrc:/IHM_Soft.qml")));

【讨论】:

以上是关于共享库中的 QQuickWindow 在 QApplication 中显示时自动关闭的主要内容,如果未能解决你的问题,请参考以下文章

QQuickWindow::grabWindow: 场景图已经在使用

为啥使用 QQuickWindow::grabWindow() 会导致窗口变成图像?

是否可以防止 C 共享库中的函数覆盖?

如何从 C++ 代码将 QML 对象转换为 QQuickWindow?

如何使用 GDB 调试共享对象库中的函数?

如何在共享库中的确切行号上设置断点?