Как исправить проблему перетаскиваемой области Qt QMainWindow с QToolBar в QGraphicsScene - PullRequest
0 голосов
/ 08 ноября 2018

Я сталкиваюсь со странной проблемой при попытке добавить QMainWindow к QGraphicsScene.Для всех намерений и целей, пожалуйста, не рекомендуйте мне использовать QMdiArea в качестве альтернативы, потому что это отвлекает от реальной проблемы, с которой я сталкиваюсь, и не соответствует моим потребностям.

Вот минимальный пример, который иллюстрирует 2 ключевые проблемы, обе из которых, я считаю, могут быть ошибками Qt.

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QToolBar>
#include <QVBoxLayout>

class MainWindow : public QMainWindow{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);

};

#endif // MAINWINDOW_H

mainwindow.cpp:

#include "mainwindow.h"


MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent){
    resize(1000, 750);

    QGraphicsView* view = new QGraphicsView;
    QGraphicsScene* scene = new QGraphicsScene;
    view->setFixedSize(1000, 750);
    view->setScene(scene);
    view->scene()->setSceneRect(-150, -150, view->size().width(), view->size().height());

    setCentralWidget(view);

    QWidget* widget = new QWidget;
    widget->resize(300, 300);
    QVBoxLayout* vLay = new QVBoxLayout;

    widget->setLayout(vLay);

    QMainWindow* testWindow = new QMainWindow;
    testWindow->resize(300, 300);

    QToolBar* toolbar = new QToolBar;
    toolbar->setFloatable(false);
    toolbar->setStyleSheet("border: 1px solid red"); //For better seeing the issue
    toolbar->addAction("Test");

    testWindow->addToolBar(toolbar);
    vLay->addWidget(testWindow);

    scene->addWidget(widget);
}

Теперь, возможно, вы царапаете голову и задаетесь вопросом, какого чёрта я это делаю ...

tl; dr: Я создаю пользовательскую область mdiв QGraphicsView с настраиваемым доком и менеджером слоев.Мне нужно, чтобы каждое подокно имело док-станцию ​​QToolBar, очень похожую на QMainWindow, но только QMainWindow поддерживает эту функцию из коробки.Каждое подокно является всеобъемлющим QWidget в моем примере выше.

Перед преобразованием "внутреннего" содержимого моего подокна в QMainWindow все работало нормально, и даже как QMainWindow все по-прежнему нормально.Однако, как только я добавляю QToolBar к QMainWindow, все начинает работать неправильно.

При запуске вы заметите, что программа выглядит правильно и что QToolBar правильно размещено и смещено.Теперь, если вы попытаетесь перетащить QToolBar куда угодно, даже за пределы QMainWindow и выполнить отпускание клавиши мыши, произойдет одно из двух:

  1. Программа выполнитсбой и очень странная трассировка стека во время работы на моей текущей системе: Qt 5.10.1 с gcc 5.2.0 на REHL

  2. QToolBar будет неправильно привязываться к неправильному месту в пределахQMainWindow.При перетаскивании и наведении курсора на допустимое место закрепления внимательно смотрите на заранее определенную прямоугольную область и используйте в качестве ориентира красную рамку.

Сбои не согласованы и иногда происходят при каждом втором событии перетаскивания послепервый.Иногда это происходит в тот момент, когда вы берете QToolBar, а иногда - после события выпадения.Я бы добавил трассировку стека, но каждый раз, когда отладчик выдает разные результаты.Я видел несколько сообщений, касающихся библиотек nVidia.so, таких как:

7fd6d96c1000-7fd6daf36000 r-xp 00000000 fd:00 34442271                   /usr/lib64/libnvidia-glcore.so.390.67
7fd6daf36000-7fd6db135000 ---p 01875000 fd:00 34442271                   /usr/lib64/libnvidia-glcore.so.390.67
7fd6db135000-7fd6db4a9000 rw-p 01874000 fd:00 34442271                   /usr/lib64/libnvidia-glcore.so.390.67
7fd6db4a9000-7fd6db4c2000 rw-p 00000000 00:00 0
7fd6db4c2000-7fd6db5d3000 r-xp 00000000 fd:00 35871194                   /usr/lib64/libGLX_nvidia.so.390.67
7fd6db5d3000-7fd6db7d3000 ---p 00111000 fd:00 35871194                   /usr/lib64/libGLX_nvidia.so.390.67
7fd6db7d3000-7fd6db7f8000 rw-p 00111000 fd:00 35871194                   /usr/lib64/libGLX_nvidia.so.390.67
7fd6db7f8000-7fd6db7ff000 rw-p 00000000 00:00 0
7fd6db7ff000-7fd6db800000 ---p 00000000 00:00 0
7fd6db800000-7fd6dc000000 rw-p 00000000 00:00 0                          [stack:30187]
7fd6dc000000-7fd6dc021000 rw-p 00000000 00:00 0
7fd6dc021000-7fd6e0000000 ---p 00000000 00:00 0
7fd6e00aa000-7fd6e00ad000 r-xp 00000000 fd:00 3060689                    /usr/lib64/tls/libnvidia-tls.so.390.67
7fd6e00ad000-7fd6e02ad000 ---p 00003000 fd:00 3060689                    /usr/lib64/tls/libnvidia-tls.so.390.67
7fd6e02ad000-7fd6e02ae000 rw-p 00003000 fd:00 3060689                    /usr/lib64/tls/libnvidia-tls.so.390.67

Отладчик может иметь более 50 неактивных обратных вызовов функций, иногда одинаковых, иногда разных.Примечательно, что я видел смешанный QPropertyAnimation в этих обратных вызовах, но не каждый раз, поэтому я не могу точно определить его и чувствую, что схожу с ума.

Теперь вы можете подумать, что это связано с тем, что QMainWindow внедряется как QGraphicsProxyWidget в QGraphicsScene и просто имеет побочный эффект от этого ... но нет.Если вместо этого вы просто добавляете только QMainWindow к сцене и обходите ее, используя QWidget, которая ее содержала, то все работает нормально.Привязка работает без проблем смещения, и больше нет сбоев.Из-за этого взаимодействия я почти уверен, что это ошибка Qt, и хотел бы отправить отчет об ошибке, используя этот пост в качестве базы.Если я что-то упустил или мне нужно обновить драйверы графики, я это сделаю.Однако это не объясняет, почему при перетаскивании привязка не соответствует расположению прямоугольника с резинкой QMainWindow's.

1 Ответ

0 голосов
/ 20 ноября 2018

Решение этой странной проблемы аналогично моему другому посту, касающемуся контекстных меню внутри QGraphicsScene. Чтобы исправить это поведение, просто установите setWindowFlags(Qt::BypassGraphicsProxyWidget) либо в виджете родительского окна, либо в самом подчиненном окне. Если вы сделаете это на родительском виджете, он будет неявно применять его к QMainWindow. Каждый раз, когда кажется, что проблема в QGraphicsScene, установка этого флажка, кажется, решает большинство ошибок / проблем.

...