c++ - QQuickView 在调用 show 时显示一个空窗口
问题描述
我仍在尝试学习使用 QML + c++ 进行编码,所以这个代码片段的本质可能听起来有点不切实际。我正在尝试编写一个继承QQuickView
并加载qml
文件的类。这是我的头文件:
#ifndef FORMLOGIN_H
#define FORMLOGIN_H
#include <QQuickView>
class FormLogin:public QQuickView
{
public:
FormLogin();
public slots:
void myHide();
};
这是它的实现:
#include "formlogin.h"
#include<QCoreApplication>
#include<QQmlEngine>
FormLogin::FormLogin()
{
this->setSource(QUrl("qrc:/main.qml"));
QObject::connect(this->engine(),&QQmlEngine::quit,&QCoreApplication::quit);
}
#include "iostream"
using namespace std;
void FormLogin::myHide(){
cout<<"called"<<endl;
if(this->isVisible()){
this->hide();
}else{
this->show();
}
}
这是我的main.cpp
:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include"formlogin.h"
#include<iostream>
#include<QTimer>
using namespace std;
FormLogin *formLogin;
QTimer *myTimer;
int main(int argc, char *argv[])
{
//QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
formLogin=new FormLogin();
myTimer=new QTimer();
myTimer->start(3000);
QObject::connect(myTimer,&QTimer::timeout,formLogin,&FormLogin::myHide);
return app.exec();
}
我的main.qml
样子是这样的:
import QtQuick 2.0
import QtQuick.Window 2.12
import QtQuick.Controls 2.5
import QtGraphicalEffects 1.0
Window {
Rectangle{
anchors.fill: parent
color: "lightblue"
}
title: qsTr("Title")
width: 450; height: 550
visible: true
}
现在,您可以从代码中QTimer
了解到它有一个连接的myHide
,它显示和隐藏我的登录表单。以下是我运行应用程序时发生的情况:
- 它打开了我设计的 QML 表单
main.qml
; - 3 秒后它会打开一个空窗口;
- 它会在 3 秒后隐藏空窗口,并继续保持这种状态。
我个人的期望是它不应该首先显示我的 QML 表单,它应该等到计时器的超时信号发出。然而,它首先显示正确的 QML 窗口,然后每次this->show
被调用时它开始显示那个奇怪的空窗口。现在是我提问的时候了:
- 为什么它显示我的 QML 窗口没有“formLogin->show()”?
- 这个空窗是什么?
- 为什么我不能隐藏我的主窗口?
解决方案
解释
问题是因为 QQuickView 需要一个项目作为根,而不是一个窗口。
问题是因为 QQuickView 需要一个元素作为根,而不是一个窗口。您的程序执行以下操作:
- 当您启动可见的窗口是 QML
- 然后出现 QQuickView 窗口
- 在它隐藏 QQuickView 并通过第 2 步之后。
步骤 1 和 2 分别回答您的问题 1 和 2。在问题 3 的情况下,答案是您只隐藏了第二个窗口。
QQmlApplicationEngine 文档中指出了这一点:
与 QQuickView 不同,QQmlApplicationEngine 不会自动创建根窗口。如果您使用 Qt Quick 中的可视项目,则需要将它们放置在 Window 内。
解决方案
所以有2个选项:
或将 Window 替换为 Item:
import QtQuick 2.0 Rectangle{ anchors.fill: parent color: "lightblue" }
#include "formlogin.h" #include<QCoreApplication> #include<QQmlEngine> #include <iostream> FormLogin::FormLogin() { setSource(QUrl("qrc:/main.qml")); connect(engine(), &QQmlEngine::quit, &QCoreApplication::quit); setTitle("Title"); resize(450, 550); } void FormLogin::myHide(){ std::cout << "called" << std::endl; setVisible(!isVisible()); }
#include <QGuiApplication> #include <QTimer> #include "formlogin.h" int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); FormLogin formLogin; QTimer myTimer; myTimer.start(3000); QObject::connect(&myTimer, &QTimer::timeout, &formLogin, &FormLogin::myHide); return app.exec(); }
或者使用 QQmlApplicationEngine 代替 QQuickView
加:
如果您想从 QML 修改窗口,那么您有 2 个选项:
或者在 C++ 插槽中实现逻辑并从 QML 调用它。
或者使用 setContextProperty 将窗口导出到 QML
FormLogin::FormLogin() { rootContext()->setContextProperty("window", this); setSource(QUrl("qrc:/main.qml")); connect(this->engine(),&QQmlEngine::quit,&QCoreApplication::quit); setTitle("Title"); resize(450, 550); }
import QtQuick 2.0 Rectangle{ id: root anchors.fill: parent color: "lightblue" Component.onCompleted: { window.flags = (window.flags | Qt.CustomizeWindowHint | Qt.FramelessWindowHint) & ~Qt.WindowTitleHint // window.showMaximized() } }
推荐阅读
- angular - 如何使用返回 void 的订阅测试函数
- windows - docker run hello-world:nanoserver 第一次工作,第二次失败。CreateContainer 期间出错
- regex - 了解正则表达式
- javascript - JS style webkit transform not appearing in inline style
- java-8 - 如何在列表流中查找 Map 中的重复值?
- shell - ssh 适用于我的自定义 shell,但无法使用 ssh 直接执行命令
- openid-connect - 使用 ADFS(2016) 为 openid-connect 传递组成员身份
- excel - 将网页中的数据提取到excel中
- java - 如何在 Swing 中检查谁提交了 repaint() 事件?
- nativescript - NativeScript:我如何在平台文件夹之外保留自定义 gradle.properties?