1.进程 (需要的资源多,所以不常用,)
进程的 QProcess
QProcess 是一个进程类
成员函数:
start(命令,参数); 启动进程执行可执行的程序
kill(); 结束进程
state(); 获取进程的状态
QProcess::Running 正在运行
QProcess::NotRuning 未运行
waitForFinished(); 等待进程结束
2.所有的代码:
ui-> 设计界面 (两个按键)
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QProcess>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private slots:
void on_pushButton_start_clicked();//开始按钮的槽函数
void on_pushButton_stop_clicked();//结束按钮的槽函数
private:
Ui::Widget *ui;
QProcess *pro; //定义一个进程
};
#endif // WIDGET_H
main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
//进程的 QProcess
/*QProcess 是一个进程类
成员函数:
start(命令,参数); 启动进程执行可执行的程序
kill(); 结束进程
state(); 获取进程的状态
QProcess::Running 正在运行
QProcess::NotRuning 未运行
waitForFinished(); 等待进程结束
*/
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QString>
#include <QDebug>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
pro = new QProcess(this);// 进程对象的初始化 绑定父亲
}
Widget::~Widget()
{
delete ui;
}
//这个槽函数可以自己生成 你在 ui 设计界面设计的时候 直接点击按键 右键,转到槽 ,这个函数就自己生成了 !!
//开始进程
void Widget::on_pushButton_start_clicked()
{
//如果进程没启动, 启动它
if(pro->state()==QProcess::NotRunning)
{
qDebug()<<"启动了进程";
//在windows上,会把路径里的斜杠,全部转为反斜杠。没说其他系统。实际上,在linux上,它并不会把反斜杠转为斜杠。所以需要我们在编码时,统一用斜杠做路径分隔符。
// : /\ 所以,一个三角形支架。按从左到右的顺序,就是斜杠和反斜杠。
QString cmd = QString("\"C:/Program Files (x86)/Tencent/QQ/Bin/QQ.exe\"");//在字符串里面 反斜杠 \ 是转义字符 斜杠/ 才是路径的
pro->start(cmd);//这个cmd 需要双引号 这是路径
}
}
//结束进程
void Widget::on_pushButton_stop_clicked()
{
qDebug()<<"关闭了进程";
//结束进程
pro->kill();
//等待结束
pro->waitForFinished();
}
3. 线程
A.Qt中通过QThread直接支持多线程
1.QThread是一个跨平台的多线程解决方案
2.QThread以简洁易用的方式实现多线程编程
QThread中的关键成员函数
2.void start()--启动函数,将线程入口地址设为为run函数
3.void terminate()--强制性结束线程
多线程编程的本质有三个方面
1.并发性是多线程的本质
2.在宏观上,所有线程并行执行
3.多喝线程间相互独立,互不干涉
同步的概念--在特殊情况下,控制多线程间的相对执行顺序
代码:
main.cpp (只用一些线程函数 和 互斥锁的使用方法)
#include <QCoreApplication>
#include <QThread>
#include <QDebug>
#include <QMutex>
#include <QMutexLocker>
#include <windows.h>//main函数里面使用 Sleep
//QMutex目的是保护一次只有一个线程访问一个对象、数据结构或一段代码。QMutex通常在较为简单的代码中使用,如果代码复杂最好使用【QMutexLocker+互斥锁】进行多线程同步,
//这样可以很容易确保锁定和解锁操作执行一致。
// 在复杂函数和语句或异常处理代码中lock和unlock QMutex很容易出错,而且很难调试。在这种情况下,可以使用QMutexLocker替代。
// QMutexLocker在一个需要锁定QMutex的函数中创建。当创建QMutexLocker时,互斥锁被锁定,后面可以使用unlock()和relock()对互斥锁进行解锁和重新锁定。如果互斥锁锁定了,
//互斥对象将在QMutexLocker销毁时被解锁。
int num = 4;//两个线程的共享资源
QMutex mut;//互斥锁
class mythreadA:public QThread
{
public:
//QThread的派生类mythreadA重写虚函数run。
void run();//线程启动,会调用run函数。
};
class mythreadB:public QThread
{
//QThread的派生类mythreadA重写虚函数run。
public:
void run();
};
void mythreadA::run()
{
QMutexLocker locker(&mut);
//mut.lock();//上锁
qDebug() << "mythreadA" << endl;
while(1)
{
num++;
qDebug()<<"numA = "<<num;
sleep(1);//线程睡眠1s.
}
mut.unlock();//解锁
}
void mythreadB::run()
{
//互斥锁方法二
QMutexLocker locker(&mut);
//mut.lock();//互斥锁的方法一
qDebug() << "mythreadB" << endl;
while(1)
{
num--;
sleep(1);//线程睡眠1s.
qDebug()<<"numB = "<<num;
}
mut.unlock();//解锁
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
mythreadA *pa = new mythreadA;//添加mythreadA对象
mythreadB *pb = new mythreadB;//添加mythreadB对象
pa->start();//启动线程pa,调用该对象的run函数
//pb->start();//启动线程pb,调用该对象的run函数
//pa->wait();//阻塞线程,直到满足其中一个条件:
//条件1.相关联的线程已经完成执行或还没有启动
//条件2.已经过了毫秒时间。如果time是ULONG_MAX(默认值),
//那么等待永远不会超时(线程必须从run()返回)。如果等待超时,该函数将返回false。
// pb->wait();
//关闭进程
//Sleep(10);//线程睡眠1s.
//pa->terminate();//停止进程的运行!
return a.exec();
}