为什么不显示 QGraphicsView
Why QGraphicsView is not shown
我的 Qt 项目中有以下代码,主要如下:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
class 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 中编译并启动。这是它的样子:
- 有一个主要window(有window经理装饰)。
- 有个child
QFrame
.
- child
QFrame
是"pressed"左上角
怎么来的?
QWidget
确保什么:Child 小部件在呈现 QWidget
时呈现(在前面)。
QWidget
不(直接)负责的内容:布局 child 小部件。
为此,必须插入布局管理器:
#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
,它将再次 re-layout qWinMain
的 children(即 qFrm
) .
我坚信 OP 的 GraphicsView
只是不可见,因为它没有最小尺寸要求。 (只是小到看不见。)
因此,添加布局管理器可确保 GraphicsView
填充 parent 小部件客户区。调整 GraphicsView
内容的大小(通过 m_Scene->setSceneRect(0, 0, 1920, 768);
)是解决此问题的另一种选择,尽管更糟糕。
最后,Qt Doc.link:Layout Management.
Layout Management
The Qt layout system provides a simple and powerful way of automatically arranging child widgets within a widget to ensure that they make good use of the available space.
Introduction
Qt includes a set of layout management classes that are used to describe how widgets are laid out in an application's user interface. These layouts automatically position and resize widgets when the amount of space available for them changes, ensuring that they are consistently arranged and that the user interface as a whole remains usable.
All QWidget subclasses can use layouts to manage their children. The QWidget::setLayout() function applies a layout to a widget. When a layout is set on a widget in this way, it takes charge of the following tasks:
- Positioning of child widgets
- Sensible default sizes for windows
- Sensible minimum sizes for windows
- Resize handling
- Automatic updates when contents change:
- Font size, text or other contents of child widgets
- Hiding or showing a child widget
- Removal of child widgets
我的 Qt 项目中有以下代码,主要如下:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
class 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 中编译并启动。这是它的样子:
- 有一个主要window(有window经理装饰)。
- 有个child
QFrame
. - child
QFrame
是"pressed"左上角
怎么来的?
QWidget
确保什么:Child 小部件在呈现 QWidget
时呈现(在前面)。
QWidget
不(直接)负责的内容:布局 child 小部件。
为此,必须插入布局管理器:
#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
,它将再次 re-layout qWinMain
的 children(即 qFrm
) .
我坚信 OP 的 GraphicsView
只是不可见,因为它没有最小尺寸要求。 (只是小到看不见。)
因此,添加布局管理器可确保 GraphicsView
填充 parent 小部件客户区。调整 GraphicsView
内容的大小(通过 m_Scene->setSceneRect(0, 0, 1920, 768);
)是解决此问题的另一种选择,尽管更糟糕。
最后,Qt Doc.link:Layout Management.
Layout Management
The Qt layout system provides a simple and powerful way of automatically arranging child widgets within a widget to ensure that they make good use of the available space.
Introduction
Qt includes a set of layout management classes that are used to describe how widgets are laid out in an application's user interface. These layouts automatically position and resize widgets when the amount of space available for them changes, ensuring that they are consistently arranged and that the user interface as a whole remains usable.
All QWidget subclasses can use layouts to manage their children. The QWidget::setLayout() function applies a layout to a widget. When a layout is set on a widget in this way, it takes charge of the following tasks:
- Positioning of child widgets
- Sensible default sizes for windows
- Sensible minimum sizes for windows
- Resize handling
- Automatic updates when contents change:
- Font size, text or other contents of child widgets
- Hiding or showing a child widget
- Removal of child widgets