2015-08-31 15 views
8

PyQt5 kullanarak bir python uygulaması yapıyorum ve bir QScrollArea kullanırken bazı sorunlarla karşılaştım. Bu 2 QScrollArea (sol ve sağ bölme) ve bir QMdiArea (merkez widget'ı) oluşan bir QHBoxLayout içine temin ettiQt.ScrollBarAsGeri gerekli olduğunda kaydırma çubuğunu göstermediniz

enter image description here

: Bu benim uygulamanın düzenidir. Denetimleri tıklatarak sol bölmedeki widget'ları genişletdiğimde ve QScrollArea'un QWidget'un yüksekliği, QScrollArea'un kendisinden daha büyükse, kaydırma çubuğu (beklendiği gibi) görünür, ancak QScrollArea içeriğinin üst üste gelmesiyle . Bu nokta her şey çalışıyor dek (Kaydırma için gerekli alanı ekleyerek resizeEvent reimplemented Bu sorunu gidermek için.

enter image description here

Şimdi, elle Ana Pencere yeniden boyutlandırma sırasında sol Bölmesi daha fazla yer ve kaydırma çubuğunu alır kaybolur (ama öyle değil) ve bölmenin widget örtüşür:

enter image description here

Ben elle de (resizeEvent alındığında) kaydırma görünürlüğünü değiştirmek çalıştı: böyle yaptığımda Başarılı bir şekilde saklayabilirim o kaydırma çubuğu ama sonra tekrar gösteremiyorum (kaydırma çubuğunda setVisible(True) çağırırsam farketmez). Bu eklenen kaydırma uzayda sonuçlanır ancak kaydırma eksik ve bölmesinde içeriği kaydırılabilir değildir:

class Pane(QScrollArea): 

    MinWidth = 186 

    def __init__(self, alignment=0, parent=None): 
     super().__init__(parent) 
     self.mainWidget = QWidget(self) 
     self.mainLayout = QVBoxLayout(self.mainWidget) 
     self.mainLayout.setAlignment(alignment) 
     self.mainLayout.setContentsMargins(0, 0, 0, 0) 
     self.mainLayout.setSpacing(0) 
     self.setContentsMargins(0, 0, 0, 0) 
     self.setFrameStyle(QFrame.NoFrame) 
     self.setFixedWidth(Pane.MinWidth) 
     self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) 
     self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded) 
     self.setSizePolicy(QSizePolicy.Maximum, QSizePolicy.Ignored) 
     self.setWidgetResizable(True) 
     self.setWidget(self.mainWidget) 

    def resizeEvent(self, resizeEvent): 
     if self.viewport().height() < self.widget().height(): 
      self.setFixedWidth(Pane.MinWidth + 18) 
      # THIS DOESN'T WORK 
      #self.verticalScrollBar().show() 
     else: 
      self.setFixedWidth(Pane.MinWidth) 
      #self.verticalScrollBar().hide() 

    def addWidget(self, widget): 
     self.mainLayout.addWidget(widget) 

    def removeWidget(self, widget): 
     self.mainLayout.removeWidget(widget) 

    def update(self, *__args): 
     for item in itemsInLayout(self.mainLayout): 
      item.widget().update() 
     super().update(*__args) 
:

İşte enter image description here

bölmesi widget uygulamasıdır

Neyi başarmak istediğim oldukça basit (ama pratik olarak basit değil): Ben sadece ihtiyaç duyulduğunda sol/sağ bölme widget'larımdaki dikey kaydırma çubuğunu dinamik olarak göstermek ve kaydırma çubuğu için gerekli alanı eklemek istiyorum. QScrollArea'daki widget'lar ile çakışmaz. Birisi sorar önce

, ben zaten böyle bir şey yapmaya çalıştık: başvurumun sonuçlanır

def resizeEvent(self, resizeEvent): 
    if self.viewport().height() < self.widget().height(): 
     self.setFixedWidth(Pane.MinWidth + 18) 
     scrollbar = self.verticalScrollbar() 
     scrollbar.setVisible(True) 
     self.setVerticalScrollBar(scrollbar) ## APP CRASH 
    else: 
     self.setFixedWidth(Pane.MinWidth) 
     #self.verticalScrollBar().hide() 

çökmesine. Umarım birileri zaten bu konuda yüzleşmiştir ve bana yardım edebilir.

DÜZENLEME: Clang kullanarak OSX Yosemite 10.10.4 altında Qt5.5 karşı derlenmiş PyQt5.5 kullanıyorum.

+0

sizin scrollArea –

+0

için 'Zaten ayarlanmış true setWidgetResizable' basan ilk deneyin: Aşağıda GÜNCELLEME

kaydırma çubukları gösterildiğinde/gizli scrollareas boyutlandırır basit bir örnek Doğru, bu yüzden sorun başka bir yerde –

cevap

3

Her şey, geçici çözümlere gerek duymadan beklediğim gibi çalışıyor gibi görünüyor. Ancak, gerçek kodunuzda, sorunuzda açıklanmayan ek kısıtlamalar olduğundan şüpheleniyorum.

import sys 
from PyQt5 import QtCore, QtGui, QtWidgets 

class Window(QtWidgets.QMainWindow): 
    def __init__(self): 
     super(Window, self).__init__() 
     widget = QtWidgets.QWidget(self) 
     layout = QtWidgets.QHBoxLayout(widget) 
     self.mdi = QtWidgets.QMdiArea(self) 
     self.leftScroll = Pane(
      QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft, self) 
     self.rightScroll = Pane(
      QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft, self) 
     layout.addWidget(self.leftScroll) 
     layout.addWidget(self.mdi) 
     layout.addWidget(self.rightScroll) 
     self.setCentralWidget(widget) 
     for scroll in self.leftScroll, self.rightScroll: 
      for index in range(4): 
       widget = QtWidgets.QTextEdit() 
       widget.setText('one two three four five') 
       scroll.addWidget(widget) 

class Pane(QtWidgets.QScrollArea): 
    MinWidth = 186 

    def __init__(self, alignment=0, parent=None): 
     super().__init__(parent) 
     self.mainWidget = QtWidgets.QWidget(self) 
     self.mainLayout = QtWidgets.QVBoxLayout(self.mainWidget) 
     self.mainLayout.setAlignment(alignment) 
     self.mainLayout.setContentsMargins(0, 0, 0, 0) 
     self.mainLayout.setSpacing(0) 
     self.setContentsMargins(0, 0, 0, 0) 
     self.setFrameStyle(QtWidgets.QFrame.NoFrame) 
     self.setFixedWidth(Pane.MinWidth) 
     self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) 
     self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) 
     self.setSizePolicy(QtWidgets.QSizePolicy.Maximum, 
          QtWidgets.QSizePolicy.Ignored) 
     self.setWidgetResizable(True) 
     self.setWidget(self.mainWidget) 
     self.verticalScrollBar().installEventFilter(self) 

    def addWidget(self, widget): 
     self.mainLayout.addWidget(widget) 

    def removeWidget(self, widget): 
     self.mainLayout.removeWidget(widget) 

    def eventFilter(self, source, event): 
     if isinstance(source, QtWidgets.QScrollBar): 
      if event.type() == QtCore.QEvent.Show: 
       self.setFixedWidth(Pane.MinWidth + source.width()) 
      elif event.type() == QtCore.QEvent.Hide: 
       self.setFixedWidth(Pane.MinWidth) 
     return super(Pane, self).eventFilter(source, event) 

if __name__ == '__main__': 

    app = QtWidgets.QApplication(sys.argv) 
    window = Window() 
    window.setGeometry(500, 300, 800, 300) 
    window.show() 
    sys.exit(app.exec_()) 
+0

teşekkürler, ben en kısa sürede ben –

+0

kodunuzu denedim deneyin ve sorun devam ediyor: http://i.imgur.com/O2o0iil.png . Kodu hangi platformda denediniz? belki sadece bir OSX meselesi. –

+0

@DanielePantaleone. Evet, başka etkenler olduğunu düşündüm. Linux'tayım ve OSX'i test edemiyorum. Sorunuzu muhtemelen, hangi OSX ve Qt sürümlerinin kullandığınızı netleştirmek için düzenlemelisiniz. OSX'te sizin için sorun yaratan en basit örneği eklediyseniz çok yardımcı olacaktır: yani belki de tek bir widget içeren tek bir QScrollArea. – ekhumoro