为什么没有显示QGraphicsView

问题描述 投票:0回答:1

我的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或在我的小部件上定义一个布局?

c++ qt qgraphicsscene
1个回答
1
投票

我做了一个更短的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开始。这是它的样子:

Snapshot of MCVE (layout missing)

  1. 有一个主窗口(窗口管理器装饰)。
  2. 有一个孩子QFrame
  3. 孩子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再次开始。这是它的样子:

Snapshot of MCVE (with layout)

现在,QFrame qFrm很好地填补了QWidget qWinMain。在qWinMain收到的调整大小事件将被转发给布局管理器qVBox,它将重新布局qWinMain(即qFrm)的孩子们。


我坚信OP的GraphicsView是不可见的,因为它没有最小的尺寸要求。 (它只是小到可见。)

因此,添加布局管理器可确保GraphicsView填充父窗口小部件客户端区域。调整GraphicsViewm_Scene->setSceneRect(0, 0, 1920, 768);)内容的大小是解决这个问题的另一个选择,尽管是更糟糕的一个。


最后,链接到Qt Doc:Layout Management

布局管理

Qt布局系统提供了一种简单而强大的方法,可以在窗口小部件中自动排列子窗口小部件,以确保它们充分利用可用空间。

Introduction

Qt包括一组布局管理类,用于描述如何在应用程序的用户界面中布置窗口小部件。当可用的空间量发生变化时,这些布局会自动定位和调整窗口小部件的大小,确保它们一致排列,并且整个用户界面仍然可用。

所有QWidget子类都可以使用布局来管理其子级。 QWidget::setLayout()函数将布局应用于窗口小部件。以这种方式在窗口小部件上设置布局时,它负责以下任务:

  • 儿童小部件的定位
  • Windows的合理默认大小
  • 窗户的最小尺寸
  • 调整处理大小
  • 内容更改时自动更新: 子窗口小部件的字体大小,文本或其他内容 隐藏或显示子窗口小部件 删除子小部件
© www.soinside.com 2019 - 2024. All rights reserved.