简体   繁体   English

在QWidget内的QGraphicsScene内绘制

[英]Draw inside a QGraphicsScene inside a QWidget

I am trying to have a window (in the form of a QWidget ) consisting of both a menu on the right and a graphics area on the left. 我正在尝试有一个窗口(以QWidget的形式),该窗口由右侧的菜单和左侧的图形区域组成。 Despite the numerous websites explaining the many ways to use QGraphicsScene and QGraphicsView , I just couldn't figure out how to do it. 尽管有许多网站解释了使用QGraphicsSceneQGraphicsView的许多方法,但我只是不知道该怎么做。

Here's main.cpp modified to work on its own : 这是对main.cpp修改,可以main.cpp工作:

#include <QApplication>
#include <QRectF>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QPushButton>
#include <QVBoxLayout>
#include <QGraphicsRectItem>
#include <QPalette>

int main (int argc, char * argv []) {
    QApplication app (argc, argv) ;

// Main window
    QWidget frame ;
    frame.setFixedSize(750, 550) ;
    frame.show() ;

// Right side, works ok
    QWidget menu (&frame) ;
    menu.setFixedSize(200, 500) ;
    menu.move(550, 10) ;
    QPalette pal = menu.palette() ;
    pal.setColor(QPalette::Background, Qt::red) ;
    menu.setPalette(pal) ; // I expected this to color the whole area 
    // to show the extent of the zone devoted to the menu,
    // but it only outlines the button
    menu.show() ;
    QPushButton button ("Menu", &menu) ;
    button.show() ; // I didn't think this was necessary,
    // but the button didn't appear without this line

// Left side, nothing displayed
    QVBoxLayout layout ;
    QGraphicsScene * scene = new QGraphicsScene () ;
    QGraphicsView view (scene) ;
    layout.addWidget(&view) ;
    QWidget canvas (&frame) ;
    canvas.setLayout(&layout) ;
    // I found this trick to include a QGraphicsScene inside a QWidget,
    // I haven't had the opportunity to see whether it really works.
    scene->addItem(new QGraphicsRectItem(10, 10, 20, 20)) ;
    // The above line has no visible effect
    view.show() ;

    return app.exec() ;
}

I would expect this to create a window, put a bunch of buttons on the right side (or in the case of the rediced code I provided, just a single button), and draw a rectangle on the left, but it leaves the whole left area blank. 我希望这会创建一个窗口,在右侧放置一堆按钮(或者,在我提供的重做代码的情况下,只是一个按钮),并在左侧绘制一个矩形,但是整个左侧区域空白。 Does the problem come from how I put the QGraphicsView inside the QWidget ? 问题是否出在我如何将QGraphicsView放在QWidget Or is it failing to draw because of something else ? 还是因为其他原因而无法绘制? Do I have to update the QGraphicsView to reflect the change ? 我是否必须更新QGraphicsView以反映更改? Is it just out of visible range ? 只是超出可见范围了吗? Finally, is the failure to draw in any way related to the fact that the whole application crashes on line QWidget canvas (&frame) ; 最后,是以任何方式绘制的失败都与整个应用程序在行QWidget canvas (&frame) ;上崩溃的事实有关QWidget canvas (&frame) ; when closed ? 什么时候关门?

I just repaired you program a bit, so that it illustrates, what you can do with Qt and how you should likely use the framework. 我只是修复了您的程序,以便说明如何使用Qt以及应该如何使用该框架。

I just moved the QPushButton to a QAction residing in a QMenuBar. 我只是将QPushButton移到驻留在QMenuBar中的QAction。 The QMenuBar can be added to a QMainWindow, which is reasonable for a normal app. 可以将QMenuBar添加到QMainWindow,这对于普通应用程序来说是合理的。

The central widget of the QMainWindow contains the QGraphicsView. QMainWindow的中央窗口小部件包含QGraphicsView。 Now, you just forgot to connect the QGraphicsScene with the QGraphicsView. 现在,您只是忘记了将QGraphicsScene与QGraphicsView连接。 That was the reasons for not seeeing anything in your view. 这就是您看不到任何东西的原因。

QGraphicsView and QGraphicsScene are just a typical example for a MVC pattern. QGraphicsView和QGraphicsScene只是MVC模式的典型示例。 You can also add another QGraphicsView and connect it to the same QGraphicsScene. 您还可以添加另一个QGraphicsView并将其连接到相同的QGraphicsScene。

You should also create all you objects with new, as Qt automatically disposes all its children of a QObject, if it is either deleted or leaves scope. 您还应该用new创建所有对象,因为Qt会自动处置QObject的所有子对象(如果它已删除或离开了作用域)。

If you are realyl interesting into seriously learning Qt I suggest, that you are creating plenty small example programs like these. 如果您对认真学习Qt感兴趣,那么我建议您创建许多这样的小型示例程序。 It really helped me a lot. 确实对我有很大帮助。

#include <QApplication>
#include <QMenuBar>
#include <QGraphicsView>
#include <QVBoxLayout>
#include <QGraphicsRectItem>
#include <QMainWindow>

int main(int argc, char* argv[]) {
    QApplication app(argc, argv);

    auto mainWindow = new QMainWindow;
    auto menuBar = new QMenuBar;
    auto menu = new QMenu("Menu");
    auto action = new QAction("Action");
    menu->addAction(action);
    menuBar->addMenu(menu);
    mainWindow->setMenuBar(menuBar);

    auto frame = new QFrame;
    frame->setLayout(new QVBoxLayout);
    mainWindow->setCentralWidget(frame);

    auto scene = new QGraphicsScene();
    auto view=new QGraphicsView(scene);
    view->setScene(scene); // That connects the view with the scene
    frame->layout()->addWidget(view);

    QObject::connect(action, &QAction::triggered, [&]() {
        scene->addItem(new QGraphicsRectItem(10, 10, 20, 20));
    });
    mainWindow->show();

    return app.exec();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM