0
votes

I'm having a bit of a problem with Qt. I'm trying to create a 2D drawing of cells, with QRect, by overloading paintEvent for a custom class which inherits QWidget and which is placed inside a QScrollArea. The problem is, paintEvent does not trigger at all (not on resize events, not when I call repaint() or update(), nor when I launch my program). Here is where I overload paintEvent, in GOL.cpp:

void GOL::paintEvent(QPaintEvent *) {

    QPainter painter(this);

    //painter.setPen(Qt::black);

    int x1Rect = rectPaint.x();
    int y1Rect = rectPaint.y();
    int x2Rect = x1Rect + rectPaint.width();
    int y2Rect = y1Rect + rectPaint.height();

    int xCell;
    int yCell = 0;

    for (int i = 0; i < rows; i++) {

        xCell = 0;

        for (int j = 0; j < cols; j++) {

            if (xCell <= x2Rect && yCell <= y2Rect && xCell + cellSize >= x1Rect &&
                    yCell + cellSize >= y1Rect) {

                if (principalMatrix->get(i,j)) {

                    painter.fillRect(xCell, yCell, cellSize - 1, cellSize - 1, cellColourAlive);
                }
                else {

                    painter.fillRect(xCell, yCell, cellSize - 1, cellSize - 1, cellColourDead);
                }
            }

            xCell += cellSize;
        }

        yCell += cellSize;
    }
}

And my layout is as follows, in DisplayGame.cpp:

DisplayGame::DisplayGame(QWidget *parent, int threads_no, int generations, char* file_in, char* file_out) :
    QWidget(parent) {

    gol = new GOL(threads_no, generations, file_in, file_out);

    QHBoxLayout *title = setupTitle();
    QHBoxLayout *buttons = setupButtons();
    QVBoxLayout *layout = new QVBoxLayout();
    scrlArea = new QScrollArea;
    scrlArea->setWidget(gol);
    layout->addLayout(title);
    layout->addWidget(scrlArea);
    layout->addLayout(buttons);
    setLayout(layout);
}

I honestly have no idea why it does not draw anything. Any ideas?

1
Does GOL provide the minimum or fixed size for its widget? - Alexander V
The size of the widget is determined by the number of rows and cols, which are written in file_in. file_in is read and the values of rows and cols are known before the paint event (file_in is read in GOL's constructor, and at the end of the constructor, I call repaint() / update(), to display the cells). - apfelin
What matters is sizeHint. Try to do: gol->setMinimumSize(gol->sizeHint()); - Alexander V
I've added what you said, after calling gol's constructor, but that didn't solve my problem, the scroll area was still empty. I've managed to get it to display my QRect matrix by adding scrlArea->setWidgetResizable(true) aftter scrlArea->setWidget(gol), yet now when the window is created, it is smaller than its contents, and no scroll bars appear. - apfelin
I've got it working now. I've added a QSize variable which is equal to the size of one cell, times the number of rows, times the number of columns, and then I set this variable as the minimum size. The only problem I have now is that the scroll bars appear even when they are not needed, and scroll way past the actual matrix. Is there a way to make them appear when needed? - apfelin

1 Answers

1
votes

I've fixed it by modifying as follows:

DisplayGame::DisplayGame(QWidget *parent, int threads_no, int generations, char* file_in, char* file_out) :
    QWidget(parent) {

    gol = new GOL(this, threads_no, generations, file_in, file_out);

    QSize *adjustSize = new QSize(gol->cellSize, gol->cellSize); //QSize object that is as big as my QRect matrix
    adjustSize->setWidth(gol->cellSize * gol->rows);
    adjustSize->setHeight(gol->cellSize * gol->cols);
    gol->setMinimumSize(*adjustSize);

    QVBoxLayout *layout = new QVBoxLayout;

    QHBoxLayout *title = setupTitle();
    layout->addLayout(title);

    QHBoxLayout *buttons = setupButtons();
    layout->addLayout(buttons);

    QPalette pal(palette()); //Setting the background black, so the white spaces between QRect items cannot be seen (though I could have modified the margins?)
    pal.setColor(QPalette::Background, Qt::black);

    scrlArea = new QScrollArea(this);
    scrlArea->setAutoFillBackground(true);
    scrlArea->setPalette(pal);
    scrlArea->setWidget(gol);

    layout->addWidget(scrlArea);

    setLayout(layout);
}

And I've left the paintEvent as it was. It was, ultimately, a size problem, as AlexanderVX said.