20190412 QT从Button开始(4)

本来这篇应该在周四晚上发的,无奈总有各种事情耽搁,下周考虑一下要不要也搞个番茄钟试试 高铁回家开始……

Buttton写到上一篇,有点黔驴技穷,希望广大同仁留言提出宝贵意见

今天主要说说QT 的线程的两种实现方式

1、继承QThread  实现 虚函数 run(),在run()里面实现线程执行内容

movetoleftthread.h

class MoveToLeftThread : public QThread  //继承
{
    Q_OBJECT
public:
    MoveToLeftThread();
    bool threadRemark;//线程是否执行控制变量
protected:
    void run();
signals:
    void moveToLeft();  //给主线程传信号

public slots:
    void stopThread();
};

movetoleftthread.cpp

MoveToLeftThread::MoveToLeftThread()
{
    threadRemark=true;//默认可以持续执行
}

void MoveToLeftThread::run()
{
    while(threadRemark)
    {
        emit moveToLeft();
        msleep(500);
    }
    threadRemark=true;//线程执行结束后,恢复可执行状态
}

void MoveToLeftThread::stopThread() //主线程触发该槽函数,结束线程执行
{
    threadRemark=false;
}

2、将线程执行放到 QObject 子类里,将QObject 子类对象 通过 moveToThread()方法,放到线程中,通过事件队列循环控制

movetorightthread.h

class MoveToRightThread : public QObject
{
    Q_OBJECT
public:
    explicit MoveToRightThread(QObject *parent = 0);

public slots:
      void doWork();//线程执行内容

  signals:
      void resultReady();//传递给主线程,结束当前线程
      void moveToRight();//控制信号
};

movetorightthread.cpp

MoveToRightThread::MoveToRightThread(QObject *parent) : QObject(parent)
{

}

void MoveToRightThread::doWork()
{
    int count =0;
    while(count<10)
    {
        count++;
        emit moveToRight();
        qDebug()<<"count "<<count;
        Sleep(1000);
    }
    emit resultReady();
}


QuickWidget.h
class QuickWidget : public QQuickWidget
{
    Q_OBJECT
public:
    QuickWidget();
    ~QuickWidget();
    void initConnection();
    MoveToLeftThread *leftThread;
    QThread rightThread;

signals:
    void moveToLeft();
    void moveToRight();
    void resetCenter();

public slots:
    void closeWindow();
    void leftButtonEvent();
    void centerButtonEvent();
    void rightButtonEvent();

    void stopMoveTOLeft();
    void stopMoveToRight();

};

quickwidget.cpp

QuickWidget::QuickWidget()
{
    QScreen *screen=qApp->primaryScreen();
    rootContext()->setContextProperty("mainWidth",screen->size().width());
    rootContext()->setContextProperty("mainHeight", screen->size().height());
    rootContext()->setContextProperty("mainWidthCell",screen->size().width()/64);
    rootContext()->setContextProperty("mainHeightCell", screen->size().height()/36);
    setResizeMode(QQuickWidget::SizeRootObjectToView);
    setSource(QUrl("qrc:/main.qml"));
    setWindowFlags(Qt::FramelessWindowHint);

    initConnection();
}

QuickWidget::~QuickWidget()
{

}

void QuickWidget::initConnection()
{
    QQuickItem *root = this->rootObject();

    connect(root,SIGNAL(closeWindow()),this,SLOT(closeWindow()));

    connect(root,SIGNAL(leftButtonEvent()),this,SLOT(leftButtonEvent()));
    connect(root,SIGNAL(centerButtonEvent()),this,SLOT(centerButtonEvent()));
    connect(root,SIGNAL(rightButtonEvent()),this,SLOT(rightButtonEvent()));

    connect(this,SIGNAL(moveToLeft()),root,SLOT(moveToLeft()));
    connect(this,SIGNAL(moveToRight()),root,SLOT(moveToRight()));
    connect(this,SIGNAL(resetCenter()),root,SLOT(resetCenter()));

    leftThread = new MoveToLeftThread; //初始化
    connect(leftThread,SIGNAL(moveToLeft()),root,SLOT(moveToLeft()),Qt::BlockingQueuedConnection);

//connect 的使用说明会放到专题讲,第五个参数 是连接的类型 阻塞队列连接

    connect(root,SIGNAL(stopMoveTOLeft()),this,SLOT(stopMoveTOLeft()));


}

void QuickWidget::closeWindow()
{
    this->close();
}

void QuickWidget::stopMoveTOLeft()
{
    qDebug()<<"stopMoveTOLeft";
    leftThread->stopThread();
    leftThread->quit();
}

void QuickWidget::leftButtonEvent()
{
    qDebug()<<tr("向左走");
   // emit moveToLeft();
    leftThread->start();

}

void QuickWidget::centerButtonEvent()
{
     qDebug()<<tr("几米的世界");
     emit resetCenter();
}

void QuickWidget::rightButtonEvent()
{
     qDebug()<<tr("向右走");
     MoveToRightThread *rightWorker = new MoveToRightThread;//实例化QObject对象
     rightWorker->moveToThread(&rightThread);//移入线程
     connect(&rightThread, &QThread::finished, rightWorker, &QObject::deleteLater);//线程结束,object对象销毁
     connect(this, &QuickWidget::moveToRight, rightWorker, &MoveToRightThread::doWork);//主线程通知线程开始执行
     connect(rightWorker,SIGNAL(moveToRight()),this->rootObject(),SLOT(moveToRight()));//
     connect(rightWorker, &MoveToRightThread::resultReady, this, &QuickWidget::stopMoveToRight);
     rightThread.start();//线程开始
     emit moveToRight();//通知线程执行
}

void QuickWidget::stopMoveToRight()
{
    rightThread.quit();//结束线程,同时会销毁Object对象
}

推荐使用第二种办法,保证线程的安全

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值