Я пытаюсь нарисовать множество Мандельброта в QT. Все сделано, и выглядит хорошо, но ему нужно некоторое время, чтобы рассчитать цвет пикселя, поэтому я хотел разделить изображение на 4 и дать расчеты для отдельных потоков.
Потоки работают, и проблема в следующем: после математики я хочу создать объект (мою структуру Pixel) и передать его в очередь с помощью метода enqueue (), который из моего paintEvent получает x, y и цвет для рисования.
Добавление в очередь создает:
18:09:15: The program has unexpectedly finished.
18:09:15: The process was ended forcefully.
без него, потоки работают нормально
метод Plot :: get_iterations_from_thread () в Plot.cpp
#include "plot.h"
QMutex Plot::mutex;
Plot::Plot(QWidget *parent) : QWidget(parent)
{
connect(this,
SIGNAL(get_iterations(unsigned int, unsigned int, int, int)),
this,
SLOT(get_iterations_from_thread(unsigned int, unsigned int, int, int)),
Qt::ConnectionType::QueuedConnection);
th1.set_values(0, (width/2)-1,
0, (height/2)-1,
cxmin, cxmax, cymin, cymax,
max_check, "TH1");
std::cout << th1.name + " values setted" << std::endl;
th2.set_values((width/2)+1, width,
0, (height/2)-1,
cxmin, cxmax, cymin, cymax,
max_check, "TH2");
std::cout << th2.name + " values setted" << std::endl;
th3.set_values(0, (width/2)-1,
(height/2)+1, height,
cxmin, cxmax, cymin, cymax,
max_check, "TH3");
std::cout << th3.name + " values setted" << std::endl;
th4.set_values((width/2)+1, width,
(height/2)+1, height,
cxmin, cxmax, cymin, cymax,
max_check, "TH4");
std::cout << th4.name + " values setted" << std::endl;
th1.start();
th2.start();
th3.start();
th4.start();
}
void Plot::get_iterations_from_thread(unsigned int iterations, unsigned int max_check, int x, int y)
{
mutex.lock();
std::cout << "generating pixel" << std::endl;
Pixel pix(x, y, iterations, max_check);
pixels.enqueue(pix);
std::cout << "pixel generated!" << std::endl;
mutex.unlock();
}
void Plot::paintEvent(QPaintEvent *e)
{
std::cout << "paintEvent" << std::endl;
mutex.lock();
QPainter painter;
painter.begin(this);
QPen pen(Qt::white);
pen.setWidth(1);
pen.setCapStyle(Qt::SquareCap);
if(!pixels.isEmpty()){
foreach(Pixel pixel, pixels){
std::cout << "painting " + std::to_string(pixel.get_x()) + "," + std::to_string(pixel.get_y()) << std::endl;
pen.setColor(pixel.get_color());
painter.setPen(pen);
painter.drawPoint(pixel.get_x(), pixel.get_y());
pixels.dequeue();
}
}
painter.end();
mutex.unlock();
}
используя его:
void CountingThread::run()
{
Plot * window = dynamic_cast<Plot*>(parent());
for(int x=x_start; x<x_stop; ++x){
for(int y=y_start; y<y_stop; ++y){
std::complex<double> c(cxmin + x/(width-1.5)*(cxmax-cxmin), cymin + y/(height-0.5)*(cymax-cymin));
std::complex<double> z(0,0);
unsigned int iterations;
for (iterations = 0; iterations < max_check && std::abs(z) < 2.0; ++iterations) {
z = z*z + c;
}
std::cout << name + " done for: " + std::to_string(x) + "," + std::to_string(y) + " " << std::endl;
//emit(window->get_iterations(iterations, max_check, x, y));
window->get_iterations_from_thread(iterations, max_check, x, y);
std::cout << name + " emitted" << std::endl;
}
}
}
и сюжет.ч
#ifndef PLOT_H
#define PLOT_H
#include <QWidget>
#include <QPainter>
#include <iostream>
#include "countingthread.h"
#include "pixel.h"
class Plot : public QWidget
{
Q_OBJECT
public:
explicit Plot(QWidget *parent = nullptr);
static QMutex mutex;
QQueue<Pixel> pixels;
private:
void Plot::paintEvent(QPaintEvent *e) override;
CountingThread th1;
CountingThread th2;
CountingThread th3;
CountingThread th4;
int width = 820;
int height = 640;
double cxmin = -1.5;
double cxmax = 0.5;
double cymin = -1.0;
double cymax = 1.0;
unsigned int max_check = 100;
signals:
void get_iterations(unsigned int iterations, unsigned int max_check, int x, int y);
public slots:
void get_iterations_from_thread(unsigned int iterations, unsigned int max_check, int x, int y);
};
#endif // PLOT_H
кстати: функция emit комментируется, потому что она не работает, и я не знаю, почему, что меня очень расстраивает