问:如何强制隐藏的小部件来计算其布局?

时间:2010-03-11 17:12:50

标签: c++ user-interface qt

我要做的是将qwidget渲染到另一个窗口(手动使用QPainter)

我有一个带有布局和一堆子控件的QWidget(w)。 w是隐藏的。在显示w之前,没有发生布局计算,这是预期的。

当我致电w->render(painter, w->mapToGlobal(QPoint(0,0))时,我得到了一堆彼此重叠的控件 w->layout()->activate();w->layout()->update()似乎没有做任何事情。

有没有办法强制布局发生而不显示w?

5 个答案:

答案 0 :(得分:17)

在窗口小部件上强制进行布局计算而不在屏幕上显示:

widget->setAttribute(Qt::WA_DontShowOnScreen);
widget->show();

show()调用将强制执行布局计算,Qt::WA_DontShowOnScreen确保未显式显示窗口小部件。

答案 1 :(得分:10)

即使窗口小部件被隐藏,也可以通过在其布局上调用invalidate()后跟activate()来强制窗口小部件的布局计算。这也会导致窗口小部件的size()sizeHint()函数返回正确和更新的值,即使尚未在该窗口小部件上调用show()

然而,有必要递归地关注所有子窗口小部件和布局,因为布局重新计算请求不会自动传播给子窗口。

以下代码显示了如何执行此操作。

/**
 * Forces the given widget to update, even if it's hidden.
 */
void forceUpdate(QWidget *widget) {
    // Update all child widgets.
    for (int i = 0; i < widget->children().size(); i++) {
        QObject *child = widget->children()[i];
        if (child->isWidgetType()) {
            forceUpdate((QWidget *)child);
        }
    }

    // Invalidate the layout of the widget.
    if (widget->layout()) {
        invalidateLayout(widget->layout());
    }
}

/**
 * Helper function for forceUpdate(). Not self-sufficient!
 */
void invalidateLayout(QLayout *layout) {
    // Recompute the given layout and all its child layouts.
    for (int i = 0; i < layout->count(); i++) {
        QLayoutItem *item = layout->itemAt(i);
        if (item->layout()) {
            invalidateLayout(item->layout());
        } else {
            item->invalidate();
        }
    }
    layout->invalidate();
    layout->activate();
}

答案 2 :(得分:1)

尝试使用QWidget::sizeHint()方法,该方法应该在布局后返回小部件的大小。

答案 3 :(得分:0)

当使用sizeHint()加上翻译画家时,这对我有用,但是我在paint()方法中这样做。

void ParentWidget::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
  painter->save();
  painter->translate(option.rect.topLeft());
  w->render(painter);
  painter->restore();
}

在这种情况下,option.rect.topLeft()为我提供了正确的展示位置。您应该尝试更合理的坐标,而不是w->mapToGlobal(QPoint(0,0)

答案 4 :(得分:0)

首先在w->layout()->update()之前调用w->layout()->activate(),我在类似问题上取得了一些成功。这似乎迫使activate()实际做某事而不是认为它很好,因为无论如何都没有显示窗口。