QML界面调用C++层阻塞函数,如何不卡界面
1.C++ 后端支持异步操作(这段需要注意)
// controller_module.h
#pragma once
#include <QObject>
#include <QtConcurrent>
#include <QFutureWatcher>class ControllerModule : public QObject
{Q_OBJECT
public:explicit ControllerModule(QObject *parent = nullptr) : QObject(parent) {}Q_INVOKABLE void setUseSolutionAsync(const QString &solution) {// 使用 QtConcurrent 在后台线程执行QFuture<void> future = QtConcurrent::run([this, solution]() {this->setUseSolution(solution); // 调用原来的同步方法});QFutureWatcher<void> *watcher = new QFutureWatcher<void>(this);connect(watcher, &QFutureWatcher<void>::finished, this, [this, watcher]() {emit setSolutionFinished();watcher->deleteLater();});watcher->setFuture(future);}// 原来的同步方法(会卡界面)void setUseSolution(const QString &solution) {// 模拟耗时操作QThread::sleep(3); // 假设这里是很耗时的操作qDebug() << "Solution set to:" << solution;// 实际的操作代码...}signals:void setSolutionStarted();void setSolutionFinished();void setSolutionError(const QString &error);
};
2.QML挡住主界面的提示框界面
// WaitDialog.qml
import QtQuick 2.15
import QtQuick.Controls 2.15Popup {id: waitDialogmodal: truedim: trueclosePolicy: Popup.NoAutoClosewidth: 200height: 120x: (parent.width - width) / 2y: (parent.height - height) / 2background: Rectangle {color: "white"radius: 8border.color: "#cccccc"}Column {anchors.centerIn: parentspacing: 15BusyIndicator {id: busyIndicatorrunning: trueanchors.horizontalCenter: parent.horizontalCenter}Text {text: "正在切换方案..."font.pixelSize: 14color: "#333333"}}
}
3.主界面,ComboBox 的切换调用C++层阻塞函数
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15Item {id: root// 等待对话框WaitDialog {id: solutionWaitDialog}ComboBox {id: solutionCombomodel: workParamsVM.solutionListLayout.fillWidth: truebackground: Rectangle {color: "#ADD8E6"radius: 3border.color: parent.down ? "#17a81a" : "#21be2b"}// 绑定到ViewModelcurrentIndex: model.indexOf(workParamsVM.solution)// 更新ViewModelonActivated: {var selectedSolution = currentText;// 先更新界面显示workParamsVM.solution = selectedSolution;// 显示等待对话框solutionWaitDialog.open();// 在后台线程执行耗时操作controllerModule.setUseSolutionAsync(selectedSolution);}}// 连接信号Connections {target: controllerModuleonSetSolutionFinished: {// 操作完成,关闭等待对话框solutionWaitDialog.close();}onSetSolutionError: {// 发生错误,关闭对话框并显示错误信息solutionWaitDialog.close();errorPopup.showError(error);}}
}