Qt5 paintEvent не вызывается внутри QScrollArea

У меня небольшая проблема с Qt. Я пытаюсь создать 2D-рисунок ячеек с QRect, перегружая paintEvent для пользовательского класса, который наследует QWidget и который помещен внутри QScrollArea. Проблема в том, что paintEvent вообще не срабатывает (ни при изменении размера, ни при вызове repaint() или update(), ни при запуске моей программы). Здесь я перегружаю paintEvent в 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;
    }
}

И мой макет выглядит следующим образом, в 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);
}

Честно говоря, я понятия не имею, почему он ничего не рисует. Любые идеи?


person apfelin    schedule 14.01.2016    source источник
comment
Предоставляет ли GOL минимальный или фиксированный размер своего виджета?   -  person Alexander V    schedule 14.01.2016
comment
Размер виджета определяется количеством rows и cols, которые записываются в file_in. file_in читается, а значения rows и cols известны до события рисования (file_in читается в конструкторе GOL, а в конце конструктора я вызываю repaint()/update() для отображения ячеек).   -  person apfelin    schedule 14.01.2016
comment
Что имеет значение, так это sizeHint. Попробуйте сделать: gol-›setMinimumSize(gol-›sizeHint());   -  person Alexander V    schedule 14.01.2016
comment
Я добавил то, что вы сказали, после вызова конструктора gol, но это не решило мою проблему, область прокрутки все еще была пустой. Мне удалось заставить его отображать мою матрицу QRect, добавив scrlArea->setWidgetResizable(true) после scrlArea->setWidget(gol), но теперь, когда окно создано, оно меньше своего содержимого, и полосы прокрутки не появляются.   -  person apfelin    schedule 14.01.2016
comment
У меня это работает сейчас. Я добавил переменную QSize, которая равна размеру одной ячейки, умноженному на количество строк, умноженное на количество столбцов, а затем установила эту переменную как минимальный размер. Единственная проблема, которая у меня есть сейчас, заключается в том, что полосы прокрутки появляются, даже когда они не нужны, и прокручиваются далеко за пределы фактической матрицы. Есть ли способ заставить их появляться, когда это необходимо?   -  person apfelin    schedule 14.01.2016
comment
У меня теперь все работает правильно, я добавлю готовый код в качестве ответа, если у кого-нибудь еще возникнет проблема с чем-то подобным.   -  person apfelin    schedule 14.01.2016
comment
Конечно, вашего кода здесь недостаточно, чтобы сделать вывод, почему он не работает.   -  person Alexander V    schedule 14.01.2016


Ответы (1)


Я исправил это, изменив следующим образом:

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);
}

И я оставил paintEvent как есть. В конечном итоге, как сказал AlexanderVX, проблема была в размере.

person apfelin    schedule 14.01.2016