Можно ли использовать QGraphicsLayout в приложении с QMainWindow?

Я надеялся, что у меня будет стандартный класс QMainWindow с меню, панелью инструментов и различными виджетами в макете, одним из которых будет графическое представление с графическим виджетом, содержащим графический макет. Но всякий раз, когда я помещаю графический вид в главное окно, ничего не отображается. Если я создаю свое графическое представление с графическим виджетом, содержащим макет внутри функции main(), то все видно.

В качестве теста я взял рабочий код, представленный в Примере базовых графических макетов Qt, создал класс QMainWindow в main и переместил создание QGraphicsScene, Window и QGraphicsView в класс основного окна.

Я протестировал класс главного окна сам по себе, и виджеты, такие как редактирование строк, отображаются нормально. Но приведенный ниже код, взятый из main в примере, больше не работает в классе главного окна.

QGraphicsScene scene;

Window *window = new Window;
scene.addItem(window);
QGraphicsView view(&scene);
view.resize(600, 600);
view.show();

Я просто получил пустую область. Если я не добавлю виджет "Окно", а вместо этого, например, нарисую эллипс, тогда это видно. Если я добавлю простой QGraphicsWidget с цветом фона, это также будет видно. Просто когда что-то находится внутри макета графического виджета, я ничего не получаю. Я искал ответы, копался в документации и даже просматривал исходники Qt, чтобы узнать, могу ли я выяснить, возможно ли то, что я пытаюсь сделать, но без какой-либо удачи.

Мое главное окно:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    QGraphicsScene scene;

    Window *window = new Window;
    window->resize(600, 600);
    scene.addItem(window);
    QGraphicsView view(&scene);
    view.resize(600, 600);
    view.show();

    setCentralWidget(&view);
    resize(600,600);
}

Код в основном:

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

    MainWindow w;
    w.show();

    return app.exec();
}

1 ответ

Решение

Одна проблема здесь:

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
   [...]

   QGraphicsView view(&scene);
   view.resize(600, 600);
   view.show();

   [...]
}

Вы объявили view виджет в стеке, что означает, что он будет автоматически уничтожен, как только ваш MainWindow конструктор возвращается, и, таким образом, пользователь никогда не увидит его. Вместо этого вы должны сделать что-то вроде этого:

QGraphicsView * view = new QGraphicsView(&scene, this);
view->resize(600, 600);
view->show();

У вас будет похожая проблема с вашим объектом QGraphicsScene:

QGraphicsScene scene;

... так как он также объявлен как локальная переменная внутри метода-конструктора, он также будет уничтожен, когда метод-конструктор вернется, оставив вас без сцены. Я предлагаю вместо этого сделать его переменной класса; Таким образом, это будет продолжаться до тех пор, пока ваш MainWindow делает.

(Обратите внимание, что объявление элементов в стеке работало в примере программы, из которой вы скопировали, только потому, что они были объявлены непосредственно в методе main(), а main() не возвращается до тех пор, пока программа не будет готова выйти. Таким образом, объекты в примере программы не будут уничтожены, пока программа все равно не завершится)

Другие вопросы по тегам