即使使用Component.onCompleted

问题描述:

也会在页面加载之前调用C++函数。下面是问题所在,我创建了一个C++类,它加载一个本地文件,并为每个新行发送一个信号。我想要做的是在我的QML文件中,我想将这些行打印到我已经完成的listview中,但现在的问题是即使在应用程序启动之前C++函数也会加载,它会读取文件并填充listview然后显示该页面。即使使用Component.onCompleted

这是我的代码。

的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++码S nippet

在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之前首先看到这个 I first see this before the GUI

那么这是GUI的存在显示并已填充 Then this is the GUI being displayed and already populated

+0

如果你的问题是把它打印出来数据然后我有一个解决方案的具体情况,你也应该知道,循环不是GUI友好的。 – eyllanesc

+0

请提出可能的解决方案。这个问题不在循环中,我想要做的就是每当我调用“SetErrorMsg”时,我希望它将消息添加到列表视图并更新gui。我想在任何其他功能中做到这一点。 –

+0

说我有一个叫做“play”的函数,我想要做的就是如果play有错误,那么我想设置错误信息并发出一个信号,当它改变时它会更新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 
}