zoukankan      html  css  js  c++  java
  • Qt Quick快速入门之线程基础

      首先必须明确的是,Qt中的线程使用是相对复杂的,并不像C#中那么随意,特别是结合串口、网络编程等,使用时稍有不慎就会出问题,然后Qt里面经常出了问题就直接崩溃(这个真是谁用谁知道),所以如果在功能上用异步方式能做到其实就没必要自己去开线程,当然如果自己写的函数比较耗时(比如不断地循环做操作之类的)就无法避免使用线程了。

      Qt中一般将耗时操作单独放在一个类中实现,在主线程中创建类对象,然后将这个对象移到子线程中,主线程与子线程间的通信主要通过信号和槽实现。另外对象是在主线程中创建的,对象中的成员都属于主线程,在主、子线程中都可以直接访问,不过如果你把对象中的成员也移到子线程中,那么在主线程就不能直接访问这个成员了。

      下面是一个使用实例。

    class ThreadManager : public QObject
    {
        Q_OBJECT
        QThread workerThread;
    public:
        ThreadManager();
        ~ThreadManager();
        MyWorker * worker;
    signals:
        void start();
    public slots:
        void emitstart();
        void emitstop();
    
        void printThreadId(int count);
    };
    ThreadManager::ThreadManager()
    {
        worker = new MyWorker();
        worker->moveToThread(&workerThread);
        connect(this,SIGNAL(start()),worker,SLOT(Start()));
        connect(worker,SIGNAL(invokeParentThreadMethod(int)),this,SLOT(printThreadId(int)));
        workerThread.start();
    }
    
    ThreadManager::~ThreadManager()
    {
        workerThread.quit();
    }
    
    void ThreadManager::emitstart()
    {
        emit start();
    }
    
    void ThreadManager::emitstop()
    {
        worker->stoped = true;
        qDebug()<<"停止";
    }
    
    void ThreadManager::printThreadId(int count)
    {
        //worker->stoped = true;
        qDebug()<<QThread::currentThreadId()<<"	"<<count;
    }

    ThreadManager 用来开启一个新的线程,然后在这个线程里面执行其他操作,下面是执行操作的类 MyWorker。

    class MyWorker : public QObject
    {
        Q_OBJECT
    public:
        explicit MyWorker(QObject *parent = 0);
        bool stoped;
    signals:
        void invokeParentThreadMethod(int count);
    public slots:
        void Start();
    };
    MyWorker::MyWorker(QObject *parent) :
        QObject(parent)
    {
        stoped = false;
    }
    
    void MyWorker::Start()
    {
        int count =0;
        stoped = false;
        while(!stoped)
        {
            qDebug()<<QThread::currentThreadId()<<"	"<<count++;
            emit invokeParentThreadMethod(count);
            QThread::msleep(500);
        }
    }


    再看看我们在主线程中如何使用的

        QObject* win = engine.rootObjects()[0];
        QObject* Button_Start = win->findChild<QObject*>("Button_Start");
        QObject* Button_Stop = win->findChild<QObject*>("Button_Stop");
    
        ThreadManager* therad = new ThreadManager();
        QObject::connect(Button_Start,SIGNAL(clicked()),therad,SLOT(emitstart()));
        QObject::connect(Button_Stop,SIGNAL(clicked()),therad,SLOT(emitstop()));

    这里只是一个很简单的线程使用示例,在串口、网络编程时往往涉及到线程同步、资源共享、线程通信等问题,比如子线程还在使用资源主线程却将资源释放了或是线程间通信时传过去的数据发生了变化等等,具体情况只有结合自己经验去分析了。

  • 相关阅读:
    localhost 和 127.0.0.1 认识
    postgreSQL可视化工具pgAdmin3 导入表结构和数据
    posgreSQL安装失败解决方案
    C#面向对象基本概念总结
    关于数据存储(关系型数据库和非关系型数据库)
    ADO.NET中的五大内置对象
    关于XML
    WPF中TreeView控件SelectedItemChanged方法的MVVM绑定
    WPF中使用MVVM进行multibinding
    WPF中TreeView控件数据绑定和后台动态添加数据(二)
  • 原文地址:https://www.cnblogs.com/Fuss/p/4353273.html
Copyright © 2011-2022 走看看