Qt Quick实现按住执行,松开停止

571 阅读2分钟

本文首发于我的博客huanghaozi.cn原链接

引言

众所周知,Qt开发跨平台应用十分的方便,qml看着也很舒服。但这次我想要实现类似按住说话的功能却没有在API里找到相关的函数(其中有一个onPressedAndHold并不能实现),如果直接用onPressedChange里面装死循环,在执行过程中按钮的状态没法变,进程会卡死在死循环里。经过大量的搜索之后,我最终还是选择了用C++对接qml实现。

多线程

在qt的C++里实现多线程非常地容易,只需要写一个类,继承自QThread(这只是方法之一),并弄一个private的run函数里面塞线程开始的代码(run函数里不能有参数,可以把参数放在类对象里)。这里我的thread需要接受一个判断按住状态的参数,所以在public加了个bool型的指针,把实现和声明分开为.h和.cpp,如下:

/****worker.h****/
#pragma once
#include <QtCore>

#ifndef WORKER_H
#define WORKER_H
class Worker : public QThread
{
public:
    bool* holding; //判断是否保持按住状态
private:
    void run(); //线程开始时执行
};
#endif

/****worker.cpp****/
#include "worker.h"
void Worker::run()
{
    int i = 0;
    while(*(this->holding)) { //循环条件是holding变量为true
        qDebug()<<"holding for "<<i<<" seconds.";
        QThread::msleep(1000); //按住时每隔一秒输出一次
        i++;
    }
}

C++与QML对接

将c++与qml对接也是需要做一个类,继承自QObject,除了将其与qml对接外,还需要与线程类对接,所以我给它整了个线程类的指针

/****qccon.h****/
#pragma once
#include "worker.h"

#ifndef QCCON_H
#define QCCON_H
class QcCon : public QObject
{
    Q_OBJECT
public:
    Worker* w; //线程对接指针
    //QCoreApplication* a;
    Q_INVOKABLE void toCpp(const QString &); //qml可调用的函数
};
#endif


/****qccon.cpp****/
#include "qccon.h"
void QcCon::toCpp(const QString &msg) //qml可调用的函数
{
    if(msg == "t") //若qml传来的消息为t,则将线程的holding变量设置为true
    {
        *(w->holding) = true;
        w->start(); //打开线程
    }
    else
        *(w->holding) = false;
    //QObject::connect(w, SIGNAL(finished()), a, SLOT(quit()));
}

main函数

main函数需要创建以上两个类的实例,并将其与qml绑定,必要的代码如下:

#include "qccon.h"
...
//main函数中加入
QcCon m;
Worker w;
m.w = &w;

engine.rootContext()->setContextProperty("qccon", &m);
//将qccon类的实例m整到qml里,对应的qml里的名字叫qccon

#QML处理 在QML里可以直接调用qccon向c++传信息了,如下

onPressedChanged: {
    if(this.pressed)
        qccon.cppMethod("t");
    else
        qccon.cppMethod("f");
}

本篇文章由一文多发平台ArtiPub自动发布