#ifndef MAINWINDOW_H#define MAINWINDOW_H#include <QMainWindow>#include <windows.h>#include <QPainter>#include <QColor>namespace Ui {class MainWindow;}class MyPoint;class MyData;class MainWindow : public QMainWindow{ Q_OBJECTpublic: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); //bool res = SetProcessAffinityMask(GetCurrentProcess(), 1); void paintVector(); static DWORD WINAPI ThreadFunction(LPVOID lpParam);protected: void virtual paintEvent(QPaintEvent*);private: Ui::MainWindow *ui; static QVector<MyPoint> vPoints; static int currentX; HANDLE handles[3]; static CRITICAL_SECTION* crSecPtr; static MyData* th1Ptr; static MyData* th2Ptr; static MyData* th3Ptr;private slots: void RepaintSlot(); void on_NoSync_clicked();};
class MyPoint { QColor m_col; QPoint m_pt;public: MyPoint(const QPoint& pt = QPoint(), QColor col = QColor(Qt::red)); void paint(QPainter& pe); ~MyPoint(){}friend class MainWindow;};class MyData : public QObject { Q_OBJECT int y; int maxX; QColor col; HANDLE hObject;public: MyData(int, int, QColor, HANDLE); ~MyData(){} void SendNeedReDraw(MyPoint&);signals: void needRedraw(MyPoint&);};
#include "mainwindow.h"#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){ ui->setupUi(this);}QVector<MyPoint> MainWindow::vPoints;MainWindow::~MainWindow(){ delete ui;}void MainWindow::paintEvent(QPaintEvent* pe) { QPainter p(this); if (vPoints.isEmpty()) return; for (int i = 0; i < vPoints.size(); i++){ vPoints[i].paint(p); }}DWORD WINAPI MainWindow::ThreadFunction(LPVOID myData){ MyPoint newPoint(QPoint(currentX, myData->y), myData->col); vPoints.append(newPoint); myData->SendNeedReDraw(myData);}void MainWindow::RepaintSlot(){ repaint();}MyPoint::MyPoint(const QPoint &pt, QColor col){ m_pt = pt; m_col = col;}void MyPoint::paint(QPainter& p){ QPen pen(m_col); pen.setWidth(5); p.setPen(pen); p.drawPoint(m_pt);}MyData::MyData(int y, int maxX, QColor col, HANDLE hObject){ this->y = y; this->maxX = maxX; this->col = col; this->hObject = hObject;}void MyData::SendNeedReDraw(MyPoint& point){ emit needRedraw(point);}void MainWindow::on_NoSync_clicked(){}
static DWORD WINAPI ThreadFunction(LPVOID lpParam);
DWORD WINAPI MainWindow::ThreadFunction(LPVOID myData){ MyPoint newPoint(QPoint(currentX, myData->y), myData->col); vPoints.append(newPoint); myData->SendNeedReDraw(myData);}
void DrawPoint(QWidget* widget, const QVector<QPoint>& point){ for (size_t i = 0; i < point.size(); i++){блокируешь мьютексрисуешь точку на виджетеразблокировал мьютекс}}
qtconcurrent::run(DrawPoint, myWidget, myPoint);
void MainWindow::paintEvent(QPaintEvent* pe) { QPainter p(this); if (vPoints.isEmpty()) return; for (int i = 0; i < vPoints.size(); i++){ vPoints[i].paint(p); }}
void MyPoint::paint(QPainter& p){ QPen pen(m_col); pen.setWidth(5); p.setPen(pen); p.drawPoint(m_pt);}
void MainWindow::on_NoSync_clicked(){}
QColor arColor[3] = {Qt::red, Qt::green, Qt::blue};void MainWindow::on_NoSync_clicked(){ // 1)подготовка к новому рисованию,почистить вектор, установиться в начало рисования, перерисовать область vPoints.clear(); currentX = 0; repaint(); const int n = 3; // задаем количество потоков int y = 200; // задаем начальную координату y int npoints = geometry().width()/4; // задаем количество точек для рисования, например так или задаем значение // объект синхронизации создан ранее в конструкторе //создаем массив динамических объектов (уничтожать будем при завершении потока), которые будем передавать в поток for (int i=0; i<n; i++) { //создаются три динамических объекта MyData (y,maxX,HANDLE hObject) pdata[i]= new MyData(y, npoints, arColor[i], 0); y+=50; //потоки для рисования создаем в заснувшем состоянии // потоковой функции передается своя структура данных handles[i] = ::CreateThread(0,0,ThreadFunction, pdata[i],CREATE_SUSPENDED,0); // связываем сигнал от объекта pdata[i] со слотом в MainWindow, который добавляет точку в вектор и перерисовывает окно QObject::connect(pdata[i], SIGNAL(needRedraw(MyPoint)), this, SLOT(addPoint(MyPoint)), Qt::BlockingQueuedConnection); } for (int i=0; i<n; i++) { //пробуждаются потоки ResumeThread(handles[i]); //закрываем дескрипторы потоков CloseHandle(handles[i]); }}