2017-08-19 2 views
0

Voici le problème, j'ai créé une classe C++ qui charge un fichier local et pour chaque nouvelle ligne il envoie un signal. Ce que je veux faire est dans mon fichier QML Je veux imprimer ces lignes dans un listview que j'ai déjà fait mais le problème est maintenant que la fonction C++ se charge avant même le démarrage de l'application, elle lirait le fichier et remplirait la listview puis affichez la page.La fonction C++ est appelée avant les chargements de page même avec Component.onCompleted

Voici mon code.

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 { 

} 

Voici le code C++ s nippet

Dans 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 

Dans 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++; 
    } 

} 

Je vois d'abord cela avant l'interface graphique I first see this before the GUI

Alors ceci est l'être GUI affiché et déjà peuplé Then this is the GUI being displayed and already populated

+0

Si votre problème est d'imprimer données alors j'ai une solution pour ce cas particulier, vous devez également savoir que les boucles ne sont pas conviviales. – eyllanesc

+0

Veuillez mettre en place la solution, cela pourrait fonctionner. Le problème n'est pas avec la boucle, ce que je veux faire c'est quand j'appelle "SetErrorMsg" Je veux qu'il ajoute le message à la liste et qu'il mette à jour le GUI. Je veux le faire dans toute autre fonction. –

+0

disons que j'ai une fonction appelée "play" ce que je veux faire est si le jeu a une erreur puis je veux définir le message d'erreur et émettre un signal qui mettra à jour le gui quand il change. –

Répondre

3

boucles sont toujours un problème dans une interface graphique, il est toujours préférable de chercher une plus conviviale de l'interface graphique, dans ce cas un 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 
}