Qt进程与Qt线程(QT四)

时间:2025-01-23 15:07:40

目录

  • 一、Qt进程
    • 1.进程的创建
      • (1)创建一个进程对象
      • (2)启动进程
      • (3)进程完成信号关联槽函数
    • 2.把mplayer播放视频嵌入到Qt界面中
      • (1)window下
      • (2)开发板---linux启动mplayer
    • 3.把window上的进程嵌入到Qt中(window平台使用)
  • 二、Qt线程
    • 中使用线程的情况
    • 线程类
    • 任务类
  • 三、把对象移动到某个线程

一、Qt进程

1.进程的创建

进程创建QProcess 类似与linux下的fork+exec函数族

用Qt中的进程启动 window下的进程

(1)创建一个进程对象

QProcess mprocess;

(2)启动进程

if(mprocess.state() == QProcess::Running)//进程正在运行中
{
    mprocess.kill();//杀死进程--要有一个过程
    mprocess.waitForFinished(1000);//阻塞--最长1000毫秒
}
//启动编辑器
mprocess.start("notepad++.exe");

(3)进程完成信号关联槽函数

//关联进程完成信号finished(int exitCode, QProcess::ExitStatus exitStatus)
//关联方式旧的关联方式
connect(&mprocess, SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(start_process(int,QProcess::ExitStatus)));

2.把mplayer播放视频嵌入到Qt界面中

(1)window下

// -slave -wid id号 4.mp4  //把mplayer嵌入到qt界面中
QStringList arglist;
arglist<<"-slave";//mplayer从模式可以接终端写入的数据(管道通信)
arglist<<"-wid";
arglist<< QString::number(ui->widget->winId());
arglist<<"F:/cc_code/Qt/004/mplayer-pc/4.mp4";
mprocess.start("F:/cc_code/Qt/004/mplayer-pc/",arglist);

(2)开发板—linux启动mplayer

#ifdef  PC//Windows启动方式
    QStringList list;
    list << "-slave";
    list << "-quiet";
    list << "-wid";
    list << QString::number(ui->display_lb->winId());
    list << path;
    mprocess->start("mplayer",list);  //如果是window,mplayer路径要自己修改
#else//开发板启动方式
    //mplayer -slave -quiet -geometry 50:50 -zoom -x 400 -y 350 /mnt/
    QString cmd("mplayer -slave -quiet -geometry ");;
    cmd.append(QString("%1:%2").arg(QString::number(ui->display_lb->x())).arg(QString::number(ui->display_lb->y())));
    cmd.append(QString(" -zoom -x %1 -y %2 ").arg(QString::number(ui->display_lb->width())).arg(QString::number(ui->display_lb->height())));
    cmd.append(path);
    mprocess->start(cmd);
#endif

3.把window上的进程嵌入到Qt中(window平台使用)

//1.获取window上面窗口的id号
//00010c84
WId wid = (WId)FindWindow(L"NeteaseYoudaoYNoteMainWnd",L"有道云笔记"); //只能运行在window平台
//2.根据winid创建QWindow窗口
QWindow *window = QWindow::fromWinId(wid);
if(window)
{
    window->setFlags(window->flags()|Qt::WindowTitleHint);
    //3.根据QWindow创建QWidget
    QWidget *myWidget = QWidget::createWindowContainer(window,ui->widget);
    myWidget->resize(ui->widget->size());
    myWidget->show();
}

二、Qt线程

所有线程共用一个进程资源

优点: 线程通信方便,调度占用的资源少

中使用线程的情况

qt中界面是运行在ui线程,槽函数也是在ui线程

如果要实时的采集数据(长时间)就用线程处理

线程类

派生QThread子类,在子类中实现线程任务函数run,把线程要做的事情放在run函数中

class ShowTime : public QThread
{
    public:
        void run()//封装线程要做的事情
        {
            while(1)
            {
                qDebug()<<QTime::currentTime().toString("hh:mm:ss");
                sleep(1);
            }
        }
};

线程通过信号把参数传递给主界面

#include <QThread>
class ShowTime : public QThread
{
    Q_OBJECT
public:
    ShowTime();
    void run();
signals:
    void sendData(QString);
    //在线程中通过信号把数据发送出去
};

#include ""
#include <QTime>
#include <QDebug>
ShowTime::ShowTime(){}
void ShowTime::run()
{
    while(1)
    {
        QString t = QTime::currentTime().toString("hh:mm:ss");
        qDebug()<<t;
        emit sendData(t);
        sleep(1);
    }
}

任务类

任务类里面不能发送信号

#include <QRunnable>
class ShowTime : public QRunnable
{
public:
    ShowTime();
    void run();
};

#include ""

#include <QTime>
#include <QDebug>
#include <QThread>
ShowTime::ShowTime(){}
void ShowTime::run()
{
    while(1)
    {
        QString t = QTime::currentTime().toString("hh:mm:ss");
        qDebug()<<t;
        QThread::sleep(1);
    }
}

    ShowTime *stime = new ShowTime();  //创建一个任务
    stime->setAutoDelete(true); //设置任务执行完后自动释放控件
    //把任务添加到线程当前线程池中
    QThreadPool::globalInstance()->start(stime);

三、把对象移动到某个线程

QObject的子类可以通moveToThread把当前对象移动某个线程中执行

创建一个QObject的子类(当然Qt中几乎所有的类多是由QOBject派生的)

#include <QObject>
class ThreadTestObject : public QObject
{
    Q_OBJECT
public:
    explicit ThreadTestObject(QObject *parent = nullptr);
signals:
public slots:
    void show_time();  //在槽函数中使用循环
};

#include ""
#include <QTime>
#include <QThread>
#include <QDebug>
ThreadTestObject::ThreadTestObject(QObject *parent) 
    : QObject(parent){}
void ThreadTestObject::show_time()
{
    while(1)
    {
        QString t = QTime::currentTime().toString();
        qDebug()<<t;
        QThread::sleep(1);
    }
}

创建ThreadTestObject对象并且把移动到线程中
    //创建ThreadTestObject对象
    ThreadTestObject *testObject = new ThreadTestObject;
    //创建一个线程
    QThread *tread = new QThread();
    testObject->moveToThread(tread);
    //启动线程
    tread->start();
    //把按钮的信号与testObject的槽函数关联(当按钮点击的时候show_time函数就会在tread线程中执行)
    connect(ui->stBt,&QPushButton::clicked,testObject,&ThreadTestObject::show_time);