我的Qt项目中有以下代码,主要有:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
类Widget是一个QWidget对象,具有以下构造函数:
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
m_Scene = new QGraphicsScene(this);
QGraphicsLinearLayout* layout = new
QGraphicsLinearLayout(Qt::Orientation::Vertical);
for(int i = 0; i < 10; i++)
{
std::string name = "m_" + std::to_string(i);
GraphicsTextItem* item = new GraphicsTextItem(nullptr, QString(name.c_str()));
layout->addItem(item);
}
QGraphicsWidget* list = new QGraphicsWidget;
list->setPos(0,0);
list->setLayout(layout);
m_Scene->addItem(list);
QGraphicsView* view = new QGraphicsView(this);
view->setScene(m_Scene);
// Why one of these lines must be uncommented?
//m_Scene->setSceneRect(0, 0, 1920, 768);
//QVBoxLayout *ttopLayout = new QVBoxLayout;
//ttopLayout->addWidget(view);
//setLayout(ttopLayout);
}
GraphicsTextItem只是一个用于显示文本的QGraphicsWidget:
class GraphicsTextItem : public QGraphicsWidget
{
public:
QString m_Name;
QColor m_Color;
public:
GraphicsTextItem(QGraphicsItem * parent = nullptr, const QString& name = QString());
void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
{
Q_UNUSED(option)
Q_UNUSED(widget)
QFont font("Times", 10);
painter->setFont(font);
painter->setPen(m_Color);
painter->drawText(0, 0, m_Name);
}
};
我的问题是为什么我的场景没有显示。我必须定义一个SceneRect或在我的小部件上定义一个布局?
我做了一个更短的MCVE用于演示:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
QWidget qWinMain;
qWinMain.resize(320, 240);
QFrame qFrm(&qWinMain);
qFrm.setFrameStyle(QFrame::Box | QFrame::Raised);
qFrm.setLineWidth(0);
qFrm.setMidLineWidth(1);
qWinMain.show();
return app.exec();
}
汇编并在cygwin64开始。这是它的样子:
QFrame
。QFrame
被“压”到左上角。怎么会?
QWidget
确实提供了什么:渲染QWidget
时渲染子窗口小部件(在前面)。
什么QWidget
不(直接)负责:布置儿童小部件。
为此,必须插入布局管理器:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
QWidget qWinMain;
qWinMain.resize(320, 240);
QVBoxLayout qVBox(&qWinMain);
QFrame qFrm(&qWinMain);
qFrm.setFrameStyle(QFrame::Box | QFrame::Raised);
qFrm.setLineWidth(0);
qFrm.setMidLineWidth(1);
qVBox.addWidget(&qFrm);
qWinMain.show();
return app.exec();
}
编辑并在cygwin64再次开始。这是它的样子:
现在,QFrame qFrm
很好地填补了QWidget qWinMain
。在qWinMain
收到的调整大小事件将被转发给布局管理器qVBox
,它将重新布局qWinMain
(即qFrm
)的孩子们。
我坚信OP的GraphicsView
是不可见的,因为它没有最小的尺寸要求。 (它只是小到可见。)
因此,添加布局管理器可确保GraphicsView
填充父窗口小部件客户端区域。调整GraphicsView
(m_Scene->setSceneRect(0, 0, 1920, 768);
)内容的大小是解决这个问题的另一个选择,尽管是更糟糕的一个。
最后,链接到Qt Doc:Layout Management。
布局管理
Qt布局系统提供了一种简单而强大的方法,可以在窗口小部件中自动排列子窗口小部件,以确保它们充分利用可用空间。
Introduction
Qt包括一组布局管理类,用于描述如何在应用程序的用户界面中布置窗口小部件。当可用的空间量发生变化时,这些布局会自动定位和调整窗口小部件的大小,确保它们一致排列,并且整个用户界面仍然可用。
所有QWidget子类都可以使用布局来管理其子级。 QWidget::setLayout()函数将布局应用于窗口小部件。以这种方式在窗口小部件上设置布局时,它负责以下任务:
- 儿童小部件的定位
- Windows的合理默认大小
- 窗户的最小尺寸
- 调整处理大小
- 内容更改时自动更新: 子窗口小部件的字体大小,文本或其他内容 隐藏或显示子窗口小部件 删除子小部件