0

尝试将 a 添加QMainWindowQGraphicsScene. 出于所有意图和目的,请不要建议我使用QMdiArea替代方案,因为这会分散我遇到的实际问题的注意力,并且不符合我的需求。

这是一个最小的例子,它举例说明了 2 个关键问题,我认为这两个问题都可能是 Qt 错误。

主窗口.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

主窗口.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:我正在使用自QGraphicsView定义 Dock 和分层管理器创建自定义 mdi 区域。我需要每个子窗口都有一个可停靠QToolBar的,就像 a 一样QMainWindow,但只有QMainWindow开箱即用的支持这个功能。QWidget在我上面的示例中,每个子窗口都是首要的。

在将我的子窗口的“内部”内容转换为 a 之前QMainWindow,一切正常,即使作为 a QMainWindow,一切仍然正常。但是,一旦我添加QToolBarQMainWindow一切都开始出错。

您会在启动时注意到程序看起来正确并且QToolBar正确放置和偏移。现在,如果您尝试拖动QToolBar任何地方,甚至在外部QMainWindow并执行鼠标键释放,将会发生以下两种情况之一:

  1. 该程序在我当前的系统上运行时会崩溃并有一个非常奇怪的堆栈跟踪:Qt 5.10.1 with gcc 5.2.0 on REHL

  2. QToolBar错误地捕捉到QMainWindow. 当拖动并悬停在有效的可停靠位置上时,仔细查看预定义的矩形区域,并使用红色边框作为指导。

崩溃是不一致的,有时会在第一个拖动事件之后每隔一个拖动事件发生一次。有时它发生在你抓住的那一刻,QToolBar而其他时候它发生在 drop 事件之后。我会添加堆栈跟踪,但每次调试器都有不同的输出。我看到了一些关于 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作为 a 嵌入其中QGraphicsProxyWidget有关,QGraphicsScene并且只是产生了副作用……但不是。如果您只将 直接添加到场景中并使用包含它QMainWindow的内容绕过,那么一切正常。QWidget捕捉没有偏移问题,也没有更多的崩溃。由于这种交互,我几乎确信这是一个 Qt 错误,并希望以这篇文章为基础提交错误报告。如果我遗漏了什么或需要更新我的图形驱动程序,我会的。QMainWindow's但是,它没有解释为什么在拖动时捕捉与橡皮筋矩形位置不匹配。

4

1 回答 1

0

这个奇怪问题的解决方案类似于我关于QGraphicsScene. 要修复此行为,只需setWindowFlags(Qt::BypassGraphicsProxyWidget)在父窗口小部件或子主窗口本身上设置。如果您在父小部件上执行此操作,它将隐式地将其应用于QMainWindow. 每当 a 中似乎存在问题时QGraphicsScene,设置上面的标志似乎可以解决大多数错误/问题。

于 2018-11-20T15:51:52.607 回答