QScrollArea中的自定义小部件只能在滚动条上重绘

时间:2018-09-22 19:57:54

标签: c++ qt qt5 qwidget qscrollarea

我正在尝试在QT中获取自定义滚动小部件,并且在滚动时遇到重绘错误。 Alt-tab或其他重绘事件会正确重绘。

我基于http://doc.qt.io/qt-5/qtwidgets-widgets-charactermap-example.html

上的示例

repeatingwidget.cpp(节选):

QSize RepeatingWidget::sizeHint() const {
    return QSize(500, itemHeight * displayItems.size() + 1);
}

void RepeatingWidget::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    painter.fillRect(event->rect(), QBrush(Qt::white));
    painter.setFont(displayFont);

    QRect itemRect = event->rect();

    int top = itemRect.top();

    QFontMetrics fontMetrics(*displayFont);
    for (auto item : displayItems) {
        painter.setPen(QPen(Qt::gray));
        painter.drawRect(itemRect.left(), top, itemRect.right(), itemHeight);
        painter.setPen(QPen(Qt::black));
        painter.drawText(8, 4 + top + fontMetrics.ascent(), item.name);

        top += itemHeight;
    }
}

mainwindow.cpp(摘录):

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
    QMenu *filemenu = menuBar()->addMenu(tr("File"));
    filemenu->addAction(tr("Quit"), this, &QWidget::close);

    auto *centralWidget = new QWidget;

    scrollArea = new QScrollArea;

    repeatingArea = new RepeatingWidget();
    scrollArea->setWidget(repeatingArea);

    auto *centralLayout = new QVBoxLayout;
    centralLayout->addWidget(scrollArea, 1);

    centralWidget->setLayout(centralLayout);

    setCentralWidget(centralWidget);
    setWindowTitle(tr("Widget Test"));
}

这似乎与示例匹配,但我遇到了charmap中未发生的重绘错误。

我尝试了setGeometrysetWidgetResizable和其他大小的策略,但仍然遇到这些重绘错误。

During first draw:

滚动后:

After scrolling

我不知道我在做什么错,因为它在重要方面与charmap中的示例代码基本相同。

这是完整的代码:https://gist.github.com/jonasbuckner/2acc1a960e457946ce4756199de3fb57

2 个答案:

答案 0 :(得分:2)

QPaintEvent是一种方法,可以使您进行智能绘画,即在必要时进行绘画,从而节省资源,例如,它为我们提供了必须通过{{1 }},这样我们就可以计算出必须绘制的项目,因为其他项目将被隐藏,因此不必绘制它们:

event->rect()

enter image description here

enter image description here

答案 1 :(得分:1)

您的原始代码不起作用,因为您正在绘制所有项目,但是使用了event-> rect,它可能只是RepeatingWidget的一部分。

有时候,要计算@eyllanesc显示的事件-> rect中的哪些项目并不容易。在这种情况下,请改用clientRect-Qt将为您裁剪图形。