Fill function in basic graphics app in Qt

1.6k views Asked by At

I have been creating a basic graphics program(like MS Paint) with simple GUI. I have two classes where one is a MainWindow which holds all buttons, sliders etc and a second class is a custom widget called drawingArea on which a user is able to draw. Basicly I've implemented most of functions, but unfortunetly I stucked at filling function, which should work just like one in MS Paint. I decided to use so called floodFill algorithm and after few hours of fighting(I am a beginner in Qt) I have managed to make it work. But not at all. The problem is I am only able to fill black-colored regions(shapes, lines, points etc) with the color I choose. But when it comes to filling different colors, it just puts one pixel in chosen color. In funcion fill(...) below I am passing two arguments - point(mouseClicked) and a color of that point. Here:

void drawingArea::fill(const QPoint &point, QColor act)
{
QPainter painter(&image);
QPen myPen(actualColor);
myPen.setWidth(1);
painter.setPen(myPen);

QQueue<QPoint> pixels;
pixels.enqueue(point);
while(pixels.isEmpty() == 0)
{
    QPoint newPoint = pixels.dequeue();
    QColor actual;
    actual.fromRgb(image.pixel(newPoint));
        if(actual == act)
        {
           painter.drawPoint(newPoint);
           update();

           QPoint left((newPoint.x()-1), newPoint.y());
           if(left.x() >0 && left.x() < image.width() && image.pixel(left) == act.rgb())
           {
               pixels.enqueue(left);
               painter.drawPoint(left);
               update();
           }

           QPoint right((newPoint.x()+1), newPoint.y());
           if(right.x() > 0 && right.x() < image.width() && image.pixel(right) == act.rgb())
           {
               pixels.enqueue(right);
               painter.drawPoint(right);
               update();
           }

           QPoint up((newPoint.x()), (newPoint.y()-1));
           if(up.y() > 0 && up.y() < image.height() && image.pixel(up) == act.rgb())
           {
               pixels.enqueue(up);
               painter.drawPoint(up);
               update();
           }

           QPoint down((newPoint.x()), (newPoint.y()+1));
           if(down.y() > 0 && down.y() < image.height() && image.pixel(down) == act.rgb())
           {
               pixels.enqueue(down);
               painter.drawPoint(down);
               update();
           }
        }
  }
}

I call this fill(...) function inside mousePressEvent here:

void drawingArea::mousePressEvent(QMouseEvent *event)
 {
 if (event->button() == Qt::LeftButton)
   {
     lastPoint = event->pos();
     QColor clr;
     clr.fromRgb(image.pixel(lastPoint));
     firstPoint = event->pos();
     isDrawing = true;
     if(isColorcheck)   colorcheck(lastPoint);
     if(isFill) fill(lastPoint,clr);
   }
 }

The really don't understand how it is working only on black color, when passing argument QColor of different colors. I would really appreciate any help or ideas.

1

There are 1 answers

0
Alexander V On

There is a fundamental problem with your code. Don't do the drawing from just any method called in your class. The drawing needs to be done in paint event callback that you define. QWidget::paintEvent worth exploring.

void MyClass::paintEvent(QPaintEvent *event)
{
     // do the drawing depending on the context and you may
     // define that context in other event handlers, etc.
}

Other than that it is hard to say what else is wrong. BTW, you can trigger drawing event by repaint() or update(). You need to consider how the exact area of redraw is defined in your code.