提交 69ca48d5 编写于 作者: mahuifa's avatar mahuifa

feat:完成QtConcurrent::map()示例

    1、使用QtConcurrent::map()在多线程环境下高效地处理大量数据;
    2、使用QtConcurrent::map()在多线程环境下批量执行成员函数。
上级 bd3e8fbe
QT += core gui
#---------------------------------------------------------------------------------------
# @功能: QtConcurrent::map使用示例
# @编译器: Desktop Qt 5.12.5 MSVC2017 64bit(也支持其它编译器)
# @Qt IDE D:/Qt/Qt5.12.5/Tools/QtCreator/share/qtcreator
#
# @开发者 mhf
# @邮箱 1603291350@qq.com
# @时间 2023-02-26 15:54:35
# @备注 1、使用QtConcurrent::map()在多线程环境下高效地处理大量数据;
# 2、使用QtConcurrent::map()在多线程环境下批量执行成员函数。
#---------------------------------------------------------------------------------------
QT += core gui concurrent
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp \
widget.cpp
HEADERS += \
widget.h
FORMS += \
widget.ui
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
HEADERS += widget.h
FORMS += widget.ui
# 定义程序版本号
VERSION = 1.0.0
DEFINES += APP_VERSION=\\\"$$VERSION\\\"
contains(QT_ARCH, i386){ # 使用32位编译器
DESTDIR = $$PWD/../bin # 程序输出路径
}else{
DESTDIR = $$PWD/../bin64 # 使用64位编译器
}
# msvc >= 2017 编译器使用utf-8编码
msvc {
greaterThan(QMAKE_MSC_VER, 1900){ # msvc编译器版本大于2015
QMAKE_CFLAGS += /utf-8
QMAKE_CXXFLAGS += /utf-8
}else{
message(msvc2015及以下版本在代码中使用pragma execution_character_set("utf-8")】指定编码)
}
}
#include "widget.h"
#include "ui_widget.h"
#include <QtConcurrent>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle(QString("QtConcurrent::map使用示例--V%1").arg(APP_VERSION));
connect(&m_futureWatcher, &QFutureWatcher<void>::started, [](){qDebug() << "开始监测";});
connect(&m_futureWatcher, &QFutureWatcher<void>::finished, [&]()
{
qDebug() << "执行完成";
m_tests.clear(); // 清空数组
});
connect(&m_futureWatcher, &QFutureWatcher<void>::progressRangeChanged, [](int minimum, int maximum) // 进度范围改变时触发信号
{
qDebug() << QString("进度范围[%1,%2]").arg(minimum).arg(maximum);
});
connect(&m_futureWatcher, &QFutureWatcher<void>::progressValueChanged, ui->progressBar, &QProgressBar::setValue); // 进度改变时触发信号(会限制进度信号发射速率,可能无法接收到所有进度)
connect(&m_futureWatcher, &QFutureWatcher<void>::progressRangeChanged, ui->progressBar, &QProgressBar::setRange);
}
Widget::~Widget()
......@@ -13,3 +29,41 @@ Widget::~Widget()
delete ui;
}
void test1(int value)
{
qDebug() << "执行数字:" << value << " thread" << QThread::currentThreadId();
QThread::sleep(1);
}
static QVector<int> datas{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 20, 100, 200};
/**
* @brief 多线程环境下高效地处理大量数据
*/
void Widget::on_pushButton_clicked()
{
QFuture<void> f1 = QtConcurrent::map(datas, test1);
m_futureWatcher.setFuture(f1);
}
void test2(TestClass* test)
{
test->run(); // 执行成员函数
delete test; // 释放成员对象
}
/**
* @brief 多线程环境下批量执行成员函数
*/
void Widget::on_pushButton_2_clicked()
{
for(int i = 0; i< 10; i++)
{
m_tests.append(new TestClass());
}
QFuture<void> f1 = QtConcurrent::map(m_tests, test2);
m_futureWatcher.setFuture(f1);
}
#ifndef WIDGET_H
#define WIDGET_H
#include <QFutureWatcher>
#include <QWidget>
#include <QDebug>
#include <QThread>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class TestClass;
class Widget : public QWidget
{
Q_OBJECT
......@@ -15,7 +19,34 @@ public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
private:
Ui::Widget *ui;
QFutureWatcher<void> m_futureWatcher; // 允许使用信号和插槽监控 QFuture
QVector<TestClass*> m_tests;
};
class TestClass {
public:
TestClass()
{
qDebug() << "创建TestClass";
}
~TestClass()
{
qDebug() << "销毁TestClass";
}
void run()
{
qDebug() << "执行对象:" << this << " thread" << QThread::currentThreadId();
QThread::sleep(1);
}
};
#endif // WIDGET_H
......@@ -6,13 +6,48 @@
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
<width>445</width>
<height>343</height>
</rect>
</property>
<property name="windowTitle">
<string>Widget</string>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QProgressBar" name="progressBar">
<property name="value">
<number>24</number>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="pushButton">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="text">
<string>使用方式1 多线程环境下高效地处理大量数据</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="pushButton_2">
<property name="maximumSize">
<size>
<width>16777215</width>
<height>50</height>
</size>
</property>
<property name="text">
<string>使用方式2 多线程环境下批量执行成员函数</string>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
......
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QThread>
#include <QtConcurrent>
......
......@@ -12,5 +12,5 @@ requires(qtHaveModule(concurrent)) # 如果条件为 false,qmake 在构建时
TEMPLATE = subdirs
SUBDIRS += RunFunction \ # QtConcurent::run使用示例,在另一个线程中运行一个函数。
Map
SUBDIRS += RunFunction # QtConcurrent::run使用示例,在另一个线程中运行一个函数。
SUBDIRS += Map # QtConcurrent::map使用示例
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册