Сигнал Qt излучает странным образом - PullRequest
0 голосов
/ 26 января 2019

У меня есть следующий код для кнопки:

emit busySignal();
QString program = "cmd";
QStringList arguments;
arguments << "";
QProcess *myProcess = new QProcess(this);
myProcess->start(program, arguments);
myProcess->write("cd C:\\Qt\\5.11.2\\mingw53_32\\bin\\\n");
myProcess->waitForBytesWritten();
myProcess->write("windeployqt C:\\Users\\BRSLV\\Desktop\\qml_collect_project\n");
myProcess->waitForBytesWritten();
myProcess->waitForFinished();
myProcess->close();
emit readySignal();

и следующий qml-код:

Model
{
    id : model
    onBusySignal: busy.running = true
    onReadySignal: busy.running = false
}
BusyIndicator {
    id: busy
    running: false

}

проблема в том, что сигналы не работают так, как я ожидаю их дляпо какой-то причине: busySignal () влияет на qml только после завершения QProcess.Может кто-нибудь сказать мне, как это исправить?Спасибо.

1 Ответ

0 голосов
/ 26 января 2019

Методы waitForXXX блокируются, поэтому они замораживают графический интерфейс, предотвращая выполнение асинхронных задач, таких как передача сигналов, поэтому решение состоит в том, чтобы использовать сигналы, чтобы знать, когда уведомлять о завершении задачи.

С другой стороны, ваш код можно уменьшить, используя setWorkingDirectory(), который заменяет команду cd.

main.cpp

#include <QGuiApplication>
#include <QProcess>
#include <QQmlApplicationEngine>

class ProcessManager: public QObject
{
    Q_OBJECT
public:
    ProcessManager(QObject *parent=nullptr):
        QObject(parent)
    {
        connect(&m_process, QOverload<int>::of(&QProcess::finished), this, &ProcessManager::readySignal);
    }
    Q_INVOKABLE void start_process(){
        emit busySignal();
        const QString program = "cmd";
        m_process.setWorkingDirectory("C:\\Qt\\5.11.2\\mingw53_32\\bin");
        m_process.start(program, {"windeployqt", "C:\\Users\\BRSLV\\Desktop\\qml_collect_project"});
    }
signals:
    void busySignal();
    void readySignal();
private:
    QProcess m_process;
};

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    qmlRegisterType<ProcessManager>("com.utils", 1, 0, "ProcessManager");
    QGuiApplication app(argc, argv);

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
        return -1;
    return app.exec();
}
#include "main.moc"

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.5

import com.utils 1.0

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")
    ProcessManager{
        id: pm
        onBusySignal: busy.running = true
        onReadySignal:  busy.running = false
    }
    BusyIndicator {
        id: busy
        running: false
    }
    Button{
        anchors.top: busy.bottom
        text: "start process"
        onClicked: pm.start_process()
    }
}
...