我正在尝试在QT中绘制Mandelbrot集。一切都完成了,看起来不错,但是需要一些时间来计算像素的颜色,所以我想将图片分割成4个,然后对分离的线程进行计算。 线程正在工作,问题是:数学运算后,我想生成对象(我的Pixel结构),并使用enqueue()方法将其传递给queque,该方法从我的paintEvent中获取x,y和color进行绘制。 添加到队列中将生成:
18:09:15: The program has unexpectedly finished.
18:09:15: The process was ended forcefully.
没有它,线程正常工作
Plot.cpp中的方法Plot :: get_iterations_from_thread()
#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;
}
}
}
和情节.h
#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函数进行注释是因为它不起作用,我也不知道为什么,这使我非常沮丧