#include
void helloThread()
{
for (int i = 0; i < 99999999; ++i) {
qDebug() << "hello";
}
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QThread* th1 = QThread::create(helloThread);
th1->start();
return a.exec();
}
void helloThread(QString s)
{
for (int i = 0; i < 99999999; ++i) {
qDebug() << "hello" << s;
}
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QThread* th1 = QThread::create(helloThread, "thread1");
th1->start();
return a.exec();
}
class A {
public:
A() { }
static void print()
{
for (int i = 0; i < 10; i++)
qDebug() << __FUNCTION__;
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QThread* th1 = QThread::create(A::print);
th1->start();
return a.exec();
}
class A {
public:
A() { }
void print()
{
for (int i = 0; i < 10; i++)
qDebug() << __FUNCTION__;
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
A aFunc;
QThread* th1 = QThread::create(&A::print, &aFunc);
th1->start();
return a.exec();
}
QThread* th2 = QThread::create([=] { qDebug() << "lamda"; });
th2->start();
QObject::connect(th2, &QThread::started, [=] { qDebug() << "th2线程启动"; });
QObject::connect(th1, &QThread::finished, [=] { qDebug() << "th1线程执行完毕";
th1->deleteLater(); });
class MyThread : public QThread {
public:
void run() override
{
for (int i = 0; i < 10; i++) {
qDebug() << "MyThread" << i;
if (i == 5)
quit(); // 只能在线程中调用,但是要等事件结束才结束
}
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
MyThread th3;
th3.start();
th3.exit(); // 结束线程,也要等事件结束才结束
return a.exec();
}
class Download : public QObject {
Q_OBJECT
public:
Download(QObject* parent = nullptr)
: QObject(parent)
{
}
public slots:
void downloadFile()
{
for (int i = 0; i < 100; i++)
qDebug() << "下载进度=====" << i << "%";
emit finished();
}
signals:
void finished();
};
class APP : public QObject {
Q_OBJECT
public:
APP(QObject* parent = nullptr)
: QObject(parent)
{
d = new Download;
th = new QThread;
connect(this, &APP::startDownload, d, &Download::downloadFile);
connect(d, &Download::finished, [=] { qDebug() << "下载完成"; });
d->moveToThread(th);
connect(th, &QThread::finished, th, &QThread::deleteLater);
th->start();
}
signals:
void startDownload();
private:
Download* d;
QThread* th;
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
APP ap;
emit ap.startDownload();
return a.exec();
}
#include "main.moc"
// 建议最多同时开多少线程数
qDebug() << QThread::idealThreadCount();
// 改变栈空间,如果线程运行所占空间很大,那就会崩溃,需要改变
qDebug() << "原始栈空间" << th3.stackSize(); // 原始栈空间 0
th3.setStackSize(1024 * 1024 * 3);
qDebug() << "现在栈空间" << th3.stackSize();//现在栈空间 3145728
调用start()函数后,新线程会优先执行run()中的代码,再执行其他的
默认run()会调用exec()函数,即启动一个局部的不占CPU的事件循环
void helloThread(QString s)
{
for (int i = 0; i < 9; ++i) {
qDebug() << "hello" << s;
QThread::sleep(1); // 睡眠1秒
QThread::msleep(100); // 睡眠100毫秒
QThread::usleep(1000); // 睡眠1000微秒
}
}
class MyThread : public QThread {
public:
void run() override
{
for (int i = 0; i < 10; i++) {
qDebug() << "MyThread" << i;
// 中断标志
if (this->isInterruptionRequested())
break;
// 请求中断
if (i == 3)
this->requestInterruption();
}
}
};
关于全局变量,在2个线程里修改会相互影响
int g_num = 5;
void fun()
{
g_num = 8;
qInfo() << "g_num" << g_num;
}
void fun1()
{
g_num = 9;
qInfo() << "1_g_num" << g_num;
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QThread* th = QThread::create(fun);
QThread* th1 = QThread::create(fun1);
th->start();
th1->start();
return a.exec();
}
可以通过QThreadStorage类把全局变量设置成线程独立的变量
QThreadStorage<int> g_num;
void fun()
{
g_num.setLocalData(8);
qInfo() << "g_num" << g_num.localData();
}
void fun1()
{
g_num.setLocalData(9);
qInfo() << "1_g_num" << g_num.localData();
}
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
QThread* th = QThread::create(fun);
QThread* th1 = QThread::create(fun1);
th->start();
th1->start();
qDebug() << "main_g_num" << g_num.localData();
return a.exec();
}
Gui框架一般只允许ui线程操作界面组件,Qt也是如此,否则会出现崩溃
通过信号与槽
参考之前的moveToThread
通过QMetaObject::invokeMethod
#include "Widget.h"
#include "./ui_Widget.h"
#include
#include
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QThread* th = QThread::create(&Widget::fun, this);
th->start();
}
Widget::~Widget()
{
delete ui;
}
void Widget::fun()
{
QThread::sleep(5);
QMetaObject::invokeMethod(ui->label, "setText", Q_ARG(QString, "hello"));
}
void Widget::on_pushButton_clicked()
{
fun();
}
#include "Widget.h"
#include "./ui_Widget.h"
#include
#include
#include
class MyEvent : public QEvent {
public:
MyEvent()
: QEvent(QEvent::Type(QEvent::User))
{
}
};
Widget::Widget(QWidget* parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::fun()
{
QCoreApplication::postEvent(this, new MyEvent);
}
void Widget::customEvent(QEvent* ev)
{
if (ev->type() == QEvent::User)
this->move(-10, 0);
}