Can't Shrink Window and Overriding Event Handlers
-
I am writing a Mandelbrot generator using QT Creator and hand coding. The UI is made up of a QMainWindow, containing a QLabel with a QPximap set from a QImage. The latter contains the calculated pixels of the mandelbrot.
I'm able to increase the size of the window, but not shrink it. I have overriden some even methods to enable dragging the Mandelbrot image (mouse press and mouse move) and zooming (mouse wheel).
I wonder I've overriden the event functions correctly? Should I call the superclass implementation? Should I call it at the beginning or the end? Or do I need to set some kind of scaling policy on one or all of the widgets?
Thanks in advance,
Tim.
-
Hi and welcome to devnet,
The questions are good however without seeing your code it's pretty much Crystal Ball Debugging (™)
Can you share your code ?
-
Thanks for the welcome. Here is my code:
#include "view.h" #include "ui_view.h" View::View(QWidget *parent) : QMainWindow(parent), ui(new Ui::View) { if (debug) { std::cout << "View::constructor" << std::endl; } ui->setupUi(this); levelsActionGroup = new QActionGroup(this); ui->action16->setActionGroup(levelsActionGroup); ui->action64->setActionGroup(levelsActionGroup); ui->action256->setActionGroup(levelsActionGroup); threadingActionGroup = new QActionGroup(this); ui->action1_CPU->setActionGroup(threadingActionGroup); ui->action2_CPU->setActionGroup(threadingActionGroup); ui->action4_CPU->setActionGroup(threadingActionGroup); ui->action8_CPU->setActionGroup(threadingActionGroup); ui->actionGPU->setActionGroup(threadingActionGroup); } /** * Redraw the image. */ void View::draw() { if (debug) { std::cout << "View::draw()" << std::endl; } image = QImage(ui->label->width(),ui->label->height(),QImage::Format_RGB888); std::thread threads[model.threads]; for (int threadNo = 0;threadNo < model.threads;threadNo++) { threads[threadNo] = std::thread(&View::drawThread,this,threadNo,model.threads); } for (int threadNo = 0;threadNo < model.threads;threadNo++) { threads[threadNo].join(); } pixmap = QPixmap::fromImage(image); ui->label->setPixmap(pixmap); } /** * Calculate every N rows of image data. * Called on a thread. */ void View::drawThread(const int& threadNo,const int& threadCount) { if (debug) { std::cout << "View::drawThread()" << std::endl; } QRgb colour; for (int x = 0; x < image.width(); x++) { for (int y = threadNo; y < image.height(); y+=threadCount) { double mandelbrotX = (x - image.width() / 2) * (model.size / image.width()) + model.centerX; double mandelbrotY = (y - image.height() / 2) * (model.size / image.width()) + model.centerY; int value = model.calc(mandelbrotX, mandelbrotY); colour = QColor::fromHsv(value*(255/model.levels), 255, 255).rgb(); image.setPixel(x, y, colour); } } } /** * Zoom. */ void View::wheelEvent(QWheelEvent* event) { // model.centerX = (event->pos().x() - image.width() / 2) * (model.size / image.width()) + model.centerX; // model.centerY = (event->pos().y() - image.height() / 2) * (model.size / image.height()) + model.centerY; if (debug) { std::cout << "View::wheelEvent(...)" << std::endl; } if (event->delta() < 0) { model.size *= 1.1; } else { model.size *= 0.9; } draw(); QMainWindow::wheelEvent(event); } /** * Start image drag. */ void View::mousePressEvent(QMouseEvent* event) { if (debug) { std::cout << "View::mousePressEvent(...)" << std::endl; } if (event->buttons().testFlag(Qt::LeftButton)) { previousMouseX = event->pos().x(); previousMouseY = event->pos().y(); dragging = true; } QMainWindow::mousePressEvent(event); } void View::mouseReleaseEvent(QMouseEvent* event) { dragging = false; QMainWindow::mouseReleaseEvent(event); } /** * Drag the image. */ void View::mouseMoveEvent(QMouseEvent* event) { if (debug) { std::cout << "View::mouseMoveEvent(...)" << std::endl; } if (dragging) { int deltaMouseX = previousMouseX - event->pos().x(); int deltaMouseY = previousMouseY - event->pos().y(); previousMouseX = event->pos().x(); previousMouseY = event->pos().y(); double mandelbrotDeltaX = deltaMouseX*(model.size / image.width()); double mandelbrotDeltaY = deltaMouseY*(model.size / image.width()); model.centerX += mandelbrotDeltaX; model.centerY += mandelbrotDeltaY; draw(); } QMainWindow::mouseMoveEvent(event); } void View::resizeEvent(QResizeEvent *event) { if (debug) { std::cout << "View::resizeEvent(...)" << std::endl; } dragging = false; draw(); QMainWindow::resizeEvent(event); } View::~View() { if (debug) { std::cout << "View::destructor" << std::endl; } delete ui; delete levelsActionGroup; delete threadingActionGroup; }
-
Part of your problem is that you are calling join in draw and that you call it from your resize function. Join will halt the current thread until the one that had join called on as finished.
Before going further, did you took a look at the Mandelbrot example in Qt's sources ? You'll see how you can generate the image from another thread without affecting your UI