即使使用 Component.onCompleted,在页面加载之前也会调用 C++ 函数
C++ function is being called before page loads even with Component.onCompleted
这就是问题所在,我创建了一个 C++ class,它加载了一个本地文件,并且对于每一个新行它都会发出一个信号。我想做的是在我的 QML 文件中,我想将这些行打印到我已经完成的列表视图中,但现在的问题是 C++ 函数甚至在应用程序启动之前加载,它会读取文件并填充列表视图然后显示页面。
这是我的代码。
main.cpp
#include <QtCore/QCoreApplication>
#include <QtGui/QGuiApplication>
#include <QtQuick/QQuickView>
#include <QtQml>
#include "boot.h"
int main(int argc, char *argv[])
{
QCoreApplication::setApplicationName("xyz");
QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
qmlRegisterType<Boot>("xyx", 1, 0, "Boot");
QGuiApplication app(argc, argv);
QQuickView quickView;
quickView.setSource(QUrl(QStringLiteral("qrc:/Boot.qml")));
quickView.setResizeMode(QQuickView::SizeRootObjectToView);
quickView.showMaximized();
return app.exec();
}
Boot.qml
import QtQuick 2.0
import "."
import QtQuick.XmlListModel 2.0
import xyz 1.0
Item{
Loader{
id: bootPageLoader
anchors.fill:parent
sourceComponent: bootSystem
focus:true
}
Component{
id:bootSystem
Rectangle{
width: 640
height: 480
color:"black"
focus:true
Component.onCompleted: {
booting.load();
}
Boot{
id:booting
onErrorMsgChanged: {
console.log("New Boot Log Message: " + errorMsg);
//This is where I am adding to the listview every time I receive a signal
logModel.append({msg:errorMsg});
log.positionViewAtEnd();
}
}
ListView {
id:log
anchors.left: parent.left
anchors.leftMargin: 10
anchors.topMargin: 10
anchors.bottomMargin:10
anchors.top: parent.top
width:(parent.width*40)/100
height:parent.height-20
model: BootLogModel{
id:logModel
}
delegate: Text {
text: msg
color: "green"
font.pixelSize: 15
}
}
Text{
id: loading
anchors{
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
text: "LOADING..."
color: "white"
font.pixelSize: Math.round(parent.height/20)
font.bold: true
}
}
}
}
BootLogModel.qml
import QtQuick 2.0
ListModel {
}
这是 C++ 代码片段
在boot.h
#ifndef BOOT_H
#define BOOT_H
#include <QObject>
#include <QString>
#include <string>
class Boot : public QObject{
Q_OBJECT
Q_PROPERTY(QString errorMsg READ errorMsg NOTIFY errorMsgChanged)
public:
explicit Boot(QObject *parent = 0);
Q_INVOKABLE void load();
QString errorMsg();
void setErrorMsg(const QString &errorMsg);
signals:
void errorMsgChanged();
private:
QString m_errorMsg;
};
#endif // BOOT_H
在boot.cpp
Boot::Boot(QObject *parent) : QObject(parent)
{
}
QString Boot::errorMsg()
{
return m_errorMsg;
}
void Boot::setErrorMsg(const QString &errorMsg)
{
m_errorMsg = errorMsg;
emit errorMsgChanged();
}
void Boot::load()
{
int i = 0;
while(i < 10000)
{
setErrorMsg("test: " + QString::number(i));
i++;
}
}
我第一次看到这个是在 GUI 之前
那么这是正在显示并已填充的 GUI
循环在 GUI 中总是一个问题,最好寻找一个更友好的 GUI 替代品,在这种情况下 QTimer
:
boot.h
int counter = 0;
bool.cpp
void Boot::load()
{
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, [timer, this](){
setErrorMsg("test: " + QString::number(counter));
counter++;
if(counter > 10000){
timer->stop();
timer->deleteLater();
}
});
timer->start(0); //delay
}
这就是问题所在,我创建了一个 C++ class,它加载了一个本地文件,并且对于每一个新行它都会发出一个信号。我想做的是在我的 QML 文件中,我想将这些行打印到我已经完成的列表视图中,但现在的问题是 C++ 函数甚至在应用程序启动之前加载,它会读取文件并填充列表视图然后显示页面。
这是我的代码。
main.cpp
#include <QtCore/QCoreApplication>
#include <QtGui/QGuiApplication>
#include <QtQuick/QQuickView>
#include <QtQml>
#include "boot.h"
int main(int argc, char *argv[])
{
QCoreApplication::setApplicationName("xyz");
QCoreApplication::setAttribute(Qt::AA_X11InitThreads);
qmlRegisterType<Boot>("xyx", 1, 0, "Boot");
QGuiApplication app(argc, argv);
QQuickView quickView;
quickView.setSource(QUrl(QStringLiteral("qrc:/Boot.qml")));
quickView.setResizeMode(QQuickView::SizeRootObjectToView);
quickView.showMaximized();
return app.exec();
}
Boot.qml
import QtQuick 2.0
import "."
import QtQuick.XmlListModel 2.0
import xyz 1.0
Item{
Loader{
id: bootPageLoader
anchors.fill:parent
sourceComponent: bootSystem
focus:true
}
Component{
id:bootSystem
Rectangle{
width: 640
height: 480
color:"black"
focus:true
Component.onCompleted: {
booting.load();
}
Boot{
id:booting
onErrorMsgChanged: {
console.log("New Boot Log Message: " + errorMsg);
//This is where I am adding to the listview every time I receive a signal
logModel.append({msg:errorMsg});
log.positionViewAtEnd();
}
}
ListView {
id:log
anchors.left: parent.left
anchors.leftMargin: 10
anchors.topMargin: 10
anchors.bottomMargin:10
anchors.top: parent.top
width:(parent.width*40)/100
height:parent.height-20
model: BootLogModel{
id:logModel
}
delegate: Text {
text: msg
color: "green"
font.pixelSize: 15
}
}
Text{
id: loading
anchors{
horizontalCenter: parent.horizontalCenter
verticalCenter: parent.verticalCenter
}
text: "LOADING..."
color: "white"
font.pixelSize: Math.round(parent.height/20)
font.bold: true
}
}
}
}
BootLogModel.qml
import QtQuick 2.0
ListModel {
}
这是 C++ 代码片段
在boot.h
#ifndef BOOT_H
#define BOOT_H
#include <QObject>
#include <QString>
#include <string>
class Boot : public QObject{
Q_OBJECT
Q_PROPERTY(QString errorMsg READ errorMsg NOTIFY errorMsgChanged)
public:
explicit Boot(QObject *parent = 0);
Q_INVOKABLE void load();
QString errorMsg();
void setErrorMsg(const QString &errorMsg);
signals:
void errorMsgChanged();
private:
QString m_errorMsg;
};
#endif // BOOT_H
在boot.cpp
Boot::Boot(QObject *parent) : QObject(parent)
{
}
QString Boot::errorMsg()
{
return m_errorMsg;
}
void Boot::setErrorMsg(const QString &errorMsg)
{
m_errorMsg = errorMsg;
emit errorMsgChanged();
}
void Boot::load()
{
int i = 0;
while(i < 10000)
{
setErrorMsg("test: " + QString::number(i));
i++;
}
}
我第一次看到这个是在 GUI 之前
那么这是正在显示并已填充的 GUI
循环在 GUI 中总是一个问题,最好寻找一个更友好的 GUI 替代品,在这种情况下 QTimer
:
boot.h
int counter = 0;
bool.cpp
void Boot::load()
{
QTimer *timer = new QTimer(this);
connect(timer, &QTimer::timeout, [timer, this](){
setErrorMsg("test: " + QString::number(counter));
counter++;
if(counter > 10000){
timer->stop();
timer->deleteLater();
}
});
timer->start(0); //delay
}