1

ユーザーが自分のプロットをその場で作成できるように、 QMdiSubWindow 内に FigureCanvasQTAgg を配置しようとしています。私はこの非常に小さな自己完結型のコードを作成しました:

from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import sys

class ExampleApp(QtGui.QMainWindow):
    def __init__(self):
        super(self.__class__, self).__init__()
        self.mdiarea = QtGui.QMdiArea()
        self.setCentralWidget(self.mdiarea)
        sub = QtGui.QMdiSubWindow(self.mdiarea)
        fig = Figure()
        p = FigureCanvas(fig)
        sub.layout().addWidget(p)
        sub.show()

def main():
    app = QtGui.QApplication(sys.argv)
    form = ExampleApp()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

この問題は、プログラムを実行して QtGui.QMdiSubWindow オブジェクトを最小化しようとすると発生します。これを行うと、プログラムはセグメンテーション違反を起こし、エラーの説明なしで終了します。これは、qt、python バインディング、または FigureCanvasQTAgg オブジェクトのエラーである可能性があります。もちろん、これらのオブジェクトを間違って使用しているのは私かもしれません。サブウィンドウを最小化するとセグメンテーション違反が発生する理由を理解し、この問題を解決する方法を見つけてください。ありがとうございました。

私の環境はubuntu 14.04で、Qtバージョンを使用しています:4.8.7 SIPバージョン:4.16.9 PyQtバージョン:4.11.4 MatplotLibバージョン:1.5.0

ドラッグ アンド ドロップ プロパティ セットの例を次に示します。それにも問題があるようです。

from PyQt4 import QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
import sys

class QtZListView(QtGui.QListView):
    def __init__(self, *args, **kwargs):
        QtGui.QListView.__init__(self, *args, **kwargs)
        self.model = QtGui.QStringListModel(['a','b','c'])
        self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.setModel(self.model)
        self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.setDragEnabled(True)

    def setStringList(self, *args, **kwargs):
        return self.model.setStringList(*args, **kwargs)

class mplsubwindow(QtGui.QMdiSubWindow):

    def __init__(self, *args, **kwargs):
        QtGui.QMdiSubWindow.__init__(self, *args, **kwargs)
        self.setWindowTitle("testing")
        self.setAcceptDrops(True)
        self.resize(400,400)
        self.show()

    def dragEnterEvent(self, event):
        print('entering')
        super(mplsubwindow, self).dragEnterEvent(event)

    def dragMoveEvent(self, event):
        print('drag moving')
        super(mplsubwindow, self).dragMoveEvent(event)

    def dropEvent(self, event):
        print('dropped')
        super(mplsubwindow, self).dropEvent(event)

class ExampleApp(QtGui.QMainWindow):
    def __init__(self):
        super(self.__class__, self).__init__()
        mainwid = QtGui.QWidget()
        self.mdiarea = QtGui.QMdiArea()

        layout = QtGui.QGridLayout(mainwid)
        layout.addWidget(self.mdiarea)
        sub = mplsubwindow(self.mdiarea)
        sub.show()
        layout.addWidget(QtZListView())
        self.setCentralWidget(mainwid)
        #self.setWidget(mainwid)

def main():
    app = QtGui.QApplication(sys.argv)
    form = ExampleApp()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()
4

2 に答える 2

1

この問題は、matplotlib ウィジェットで報告されている不適切なサイズを中心に展開しているようです。@tcaswell が指摘しているように、これがセグメンテーション違反を引き起こさないように、matplotlib を修正する必要があります。

私は反対側から問題を攻撃し、Qt が偽の寸法を報告するのを止めようとします。「組み込み」レイアウトを使用すると問題が発生するようです。これは、レイアウトの存在がQMdiSubWindowfromによって継承されているためである可能性がありますが、likelyQWidgetの実装ではQMdiSubWindowそれが正しく使用されていません。メソッドを使用しQMdiSubWindow.setWidget()、独自のレイアウトを作成する限り、segfault は回避されます。

自分で管理するレイアウトのコード例を次に示します。

p = FigureCanvas(fig)
container = QtGui.QWidget()
layout = QtGui.QVBoxLayout(container)
layout.addWidget(p)        
sub.setWidget(container)

編集

基礎となる C++ 実装を見ると、ウィジェットをレイアウトに追加するだけでなく、 への呼び出しがQMdiSubWindow.setWidget()はるかに複雑であることがわかります。

于 2016-03-14T09:12:11.950 に答える