Resize eines QVBoxLayouts

Verschiedenes zu Qt
Antworten
olebole
Beiträge: 38
Registriert: 20. März 2009 16:39

Resize eines QVBoxLayouts

Beitrag von olebole »

Hallo,

ich habe ein Fenster (bzw. ein DockWidget), das aus einem Hauptwidget und einem dazugehörigen horizintalen QScrollBar besteht. die beiden sind per QVBoxLayout in das Fenster eingebunden.

Das Hauptwidget besteht aus einem (matplotlib)-Diagramm und benötigt zum Neuzeichnen immer einige Millisekunden.

Wenn ich jetzt die Fenstergröße ändere, erscheint der Scrollbalken nicht immer korrekt: er wird entweder an der falschen Stelle gezeichnet (bei Änderung der Fensterhöhe), oder hat die falsche Größe (bei Änderung der Fensterbreite). Teilweise liegt er komplett außerhalb des Fensters und ist damit unbedienbar.

Ich habe mal die resizeEvent()- bzw. moveEvent()-Funktionen des Hauptwidgets und der Scrollbar überschrieben, um zu sehen, was da passiert. Offensichtlich kommen die Events in der falschen Reihenfolge:
(hier für eine Änderung der Fensterbreite):

Code: Alles auswählen

figure resize to QSize(803, 474) <-- erstes Event
figure resize to QSize(879, 474) <-- zweites Event
scroll resize to QSize(879, 15)  <-- zweites Event (falsch!!)
scroll resize to QSize(803, 15)  <-- erstes Event
Ich interpretiere das so:
  • das Hauptwidget erhält das erste Event und zeichnet sich selbst neu (*). Das dauert einige Zeit.
  • in dieser Zeit kommt das zweite Resize-Event.
  • weil das Widget bereits in einem Zeichen-Prozess ist, wird der zweite Request ignoriert (oder in eine Warteschlange gesetzt) und wird unmittelbar beendet.
  • das führt zur Verarbeitung des zweiten Events in der Scrollbar
  • nachdem das erste Neuzeichnen beendet ist, beginnt die Verarbeitung des ersten Events in der Scrollbar.
Wer macht hier was falsch?
  • Qt, weil es die Events nicht in der korrekten Reihenfolge liefert?
  • FigureCanvas (bzw. matplotlib), weil es die Verarbeitung des zweiten Events beendet, während das erste noch verarbeitet wird?
  • oder ich, weil ich irgendwas nicht verstanden habe?
Und, noch wichtiger: wie kann ich das vermeiden?

Viele Grüße

olebole
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Beitrag von archer »

Erzeugst due das Hauptfenster und die Scrollbar zur Laufzeit (per Quellcode)?
Hast du evtl. den Parent nicht richtig vergeben?
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Event. wäre der Quellcode hierzu nicht schlecht...
olebole
Beiträge: 38
Registriert: 20. März 2009 16:39

Beitrag von olebole »

upsala hat geschrieben:Event. wäre der Quellcode hierzu nicht schlecht...
Kein Problem. Er ist zwar in Python, sollte aber trotzdem verständlich sein.
Falls nicht, kann ich gerne erklären.

Code: Alles auswählen

import random
import sys

from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure,SubplotParams

class DiagramWidget(QtGui.QWidget):
    def __init__(self, parent):
        QtGui.QWidget.__init__(self, parent)
        layout = QtGui.QVBoxLayout(self)
        self.setLayout(layout)
        self.diagram = InnerDiagramWidget(self)
        self.scrollbar = QtGui.QScrollBar(QtCore.Qt.Horizontal, self)
        layout.addWidget(self.diagram)
        layout.addWidget(self.scrollbar)
    
class InnerDiagramWidget(FigureCanvas):
    def __init__(self, parent):
        fig = Figure()
        self.axes = fig.add_subplot(111)
        range = xrange(10000)
        l = [ random.randint(-5, 5) for i in range ]
        self.axes.plot(range, l, drawstyle='steps')
        FigureCanvas.__init__(self, fig)
        self.setParent(parent)
        FigureCanvas.setSizePolicy(self,
                                   QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

a = QtGui.QApplication(sys.argv)
w = QtGui.QMainWindow()
w.setCentralWidget(DiagramWidget(w))
w.show()
a.exec_()
Antworten