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.15

Popup {
    id: waitDialog
    modal: true
    dim: true
    closePolicy: Popup.NoAutoClose
    
    width: 200
    height: 120
    x: (parent.width - width) / 2
    y: (parent.height - height) / 2

    background: Rectangle {
        color: "white"
        radius: 8
        border.color: "#cccccc"
    }

    Column {
        anchors.centerIn: parent
        spacing: 15

        BusyIndicator {
            id: busyIndicator
            running: true
            anchors.horizontalCenter: parent.horizontalCenter
        }

        Text {
            text: "正在切换方案..."
            font.pixelSize: 14
            color: "#333333"
        }
    }
}

3.主界面,ComboBox 的切换调用C++层阻塞函数
 

import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 1.15

Item {
    id: root

    // 等待对话框
    WaitDialog {
        id: solutionWaitDialog
    }

    ComboBox {
        id: solutionCombo
        model: workParamsVM.solutionList
        Layout.fillWidth: true

        background: Rectangle {
            color: "#ADD8E6"
            radius: 3
            border.color: parent.down ? "#17a81a" : "#21be2b"
        }

        // 绑定到ViewModel
        currentIndex: model.indexOf(workParamsVM.solution)

        // 更新ViewModel
        onActivated: {
            var selectedSolution = currentText;
            
            // 先更新界面显示
            workParamsVM.solution = selectedSolution;
            
            // 显示等待对话框
            solutionWaitDialog.open();
            
            // 在后台线程执行耗时操作
            controllerModule.setUseSolutionAsync(selectedSolution);
        }
    }

    // 连接信号
    Connections {
        target: controllerModule
        onSetSolutionFinished: {
            // 操作完成,关闭等待对话框
            solutionWaitDialog.close();
        }
        
        onSetSolutionError: {
            // 发生错误,关闭对话框并显示错误信息
            solutionWaitDialog.close();
            errorPopup.showError(error);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值