我有一个小工具W
派生自QFrame
,其布局设置为QVBoxLayout
的实例。我想知道以下resizeEvent
实现是否正确或是否会导致无限循环:
void W::resizeEvent(QResizeEvent *event) {
for (/* some condition based on the new size of this widget */) {
// Infinite loop or not?
qobject_cast<QVBoxLayout *>(layout())->addWidget(new QWidget());
}
}
到目前为止它对我有用,这是纯粹的运气吗?
答案 0 :(得分:1)
这没关系。 W
拥有拥有QLayout
的{{1}}。将QWidget
添加到QWidget
不会更改QLayout
的大小。你总是这样看。例如,如果将子窗口小部件放在父窗口中并且父窗口太小,则子窗口小部件将被剪切。在状态上不同,父母的大小不会延伸以适应孩子的大小。我相信您的代码是基于父级大小隐藏或显示小部件的典型方式(例如,当窗口大小更改时)。
答案 1 :(得分:1)
绘制和构建小部件的层次结构是两回事。因此,添加QWidget
就好了,但直接在QPainter
中使用resizeEvent
。
QWidget
s
QWidget
s衍生物(QLineEdit
,QPushButton
,......)的层次结构是图形用户界面应如何显示的高级规范,可以使用{ {1}}项目。
<强>绘画强>
绘画(使用QLayout
)是在屏幕上实际绘制内容的过程,纯粹是在虚拟函数QWidget::paintEvent
中完成的。 QPainter
的每个派生都应该提供这个空基函数的实现。默认导数(QWidget
,...)根据其当前状态(窗口小部件的大小,QLineEdit
的当前文本,...)提供paintEvent
的实现。当前QLineEdit
对象,通常根据您的操作系统自动设置,但可以使用QWidget::setStyle
或QApplication::setStyle
以编程方式进行更改。可以使用QWidget::update
请求重新绘制。
&#34;不应该/不需要&#34; vs&#34;可能不会&#34;
句子&#34; 在此处理程序中不需要(或应该)完成绘图。&#34;适用于实现自定义QStyle
(使用QWidget
的新实现)的人员,以明确您不应在此处实现您的绘画,但会自动触发paintEvent
。
"Should not/need not"是一些建议,他们不会写#34;可能不会&#34;。因此,如果由于某种原因(例如实时应用程序)想要立即刷新屏幕,则可以使用重绘立即调用重绘,从而在paintEvent
期间调用paintEvent
。只要resizeEvent
上的所有QPainter
操作都在QWidget
内(根据warning in the QPainter documentation的要求),一切都很好。
答案 2 :(得分:1)
在addWidget
函数中使用resizeEvent
在布局中添加小部件不是问题,因为它不会立即触发绘图。
您可以通过编译和执行这个简单的项目轻松验证这一点:
<强> dialog.h:强>
#pragma once
#include <QDialog>
class Dialog : public QDialog
{
Q_OBJECT
public:
Dialog(QWidget *parent = 0);
~Dialog();
void resizeEvent(QResizeEvent *event);
void paintEvent(QPaintEvent *event);
private:
bool resizing;
};
<强> dialog.cpp:强>
#include "dialog.h"
#include <QResizeEvent>
#include <QVBoxLayout>
#include <QPushButton>
#include <QDebug>
Dialog::Dialog(QWidget *parent)
: QDialog(parent),
resizing(false)
{
new QVBoxLayout(this);
}
Dialog::~Dialog()
{
}
void Dialog::resizeEvent(QResizeEvent *event)
{
resizing = true;
if ( event->size().width() == event->size().height() )
{
qDebug() << "Adding widget";
// Infinite loop or not?
layout()->addWidget(new QPushButton());
}
resizing = false;
}
void Dialog::paintEvent(QPaintEvent *event)
{
if ( resizing )
{
qDebug() << "Painting while resizing widget";
}
}
<强> main.cpp中:强>
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
return a.exec();
}
当你运行程序时,调整对话框的大小使其为正方形(宽度==高度),插入一些按钮(&#34;添加小部件&#34;打印到控制台),但你&#39;永远不会看到&#34;绘画时调整小部件&#34;信息。这很可能是因为addWidget
设置了一个脏显示标志,稍后由框架处理。它使显示无效,但不会立即重新绘制。
所以你正在做的事情很好并且没有违反框架要求(&#34;在这个处理程序中不需要(或应该)完成绘图。&#34;)。
然而,如果你没有信心(也许这幅画可以在不同的操作系统上立即操作,或者在将来的Qt版本中......你无法确定),你也可以通过发射来延迟插入使用Qt::QueuedConnection
连接到插槽的信号,此插槽将被执行&#34;稍后&#34;然后拨打addWidget
电话,保证在resizeEvent
功能之外完成。