为什么不显示QGraphicsView

时间:2019-04-02 16:35:19

标签: c++ qt qgraphicsscene

我的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还是定义一个布局?

1 个答案:

答案 0 :(得分: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填充父窗口小部件客户区域。调整GraphicsView的内容大小(通过m_Scene->setSceneRect(0, 0, 1920, 768);)是解决此问题的另一种方法,尽管更糟。


最后,指向Qt文档的链接:Layout Management

  

布局管理

     

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

     

简介

     

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

     

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

     
      
  • 子窗口小部件的位置
  •   
  • 适用于Windows的默认大小
  •   
  • 窗口的最小尺寸
  •   
  • 调整大小处理
  •   
  • 内容更改时自动更新:      
        
    • 子窗口小部件的字体大小,文本或其他内容
    •   
    • 隐藏或显示子窗口小部件
    •   
    • 删除子小部件
    •   
  •