2

I'm trying to incorporate a QSplitter. The code works perfectly from a functionality standpoint, but the QSplitter itself doesn't appear correctly under the default PyQt style... possibly because it is itself embedded within a vertical splitter. This is confusing for the user.

If you uncomment out the line (and thus change the default PyQt style), the QSplitter visualizes correctly only when hovered over... however, I also don't want this other style.

Can anyone provide any guidance on this matter?

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class Example(QWidget):

   def __init__(self):
       super(Example, self).__init__()  
       self.initUI()

   def initUI(self):

       hbox = QHBoxLayout(self)

       L_layout = QGridLayout()
       R_layout = QGridLayout()

       L_widgets = QWidget()
       L_widgets.setLayout(L_layout)

       R_widgets = QWidget()
       R_widgets.setLayout(R_layout)

       topleft = QFrame()
       topleft.setFrameShape(QFrame.StyledPanel)

       btn1 = QPushButton('btn1')

       bottom = QFrame()
       bottom.setFrameShape(QFrame.StyledPanel)
       textedit = QTextEdit()

       L_layout.addWidget(topleft, 0, 0, 1, 1)
       L_layout.addWidget(btn1, 1, 0, 1, 1)
       R_layout.addWidget(textedit)

       splitter1 = QSplitter(Qt.Horizontal,frameShape=QFrame.StyledPanel,frameShadow=QFrame.Plain)
       splitter1.addWidget(L_widgets)
       splitter1.addWidget(R_widgets)
       splitter1.setStretchFactor(1,1)

       splitter2 = QSplitter(Qt.Vertical)
       splitter2.addWidget(splitter1)
       splitter2.addWidget(bottom)

       hbox.addWidget(splitter2)

       self.setLayout(hbox)
       #QApplication.setStyle(QStyleFactory.create('Cleanlooks'))

       self.setGeometry(300, 300, 300, 200)
       self.setWindowTitle('QSplitter demo')
       self.show()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Image1

Image2


EDIT: This is apparently a known macOS bug. When viewed on Linux, the bar of splitter1 has the same look as splitter2. I'll leave this topic open in case anyone else knows of a suitable workaround for mac.

ees
  • 327
  • 1
  • 17

1 Answers1

1

Because the QPushButton has default minimum size, when you want to move splitter to left,
the button has reached its minimum size. So you can not move left anymore, otherwise the left will will collapse.

So if you want the left showing as you want, you can set the minimum size off button widget.

import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *

class Example(QWidget):

   def __init__(self):
       super(Example, self).__init__()  
       self.initUI()

   def initUI(self):

       hbox = QHBoxLayout(self)

       L_layout = QGridLayout()
       R_layout = QGridLayout()

       L_widgets = QWidget()
       L_widgets.setLayout(L_layout)

       R_widgets = QWidget()
       R_widgets.setLayout(R_layout)

       topleft = QFrame()
       topleft.setFrameShape(QFrame.StyledPanel)

       btn1 = QPushButton('btn1')
       btn1.setMinimumWidth(1)  # For example : set the minimum width to 1, then you can move left until the btn1 width is 1

       bottom = QFrame()
       bottom.setFrameShape(QFrame.StyledPanel)
       textedit = QTextEdit()

       L_layout.addWidget(topleft, 0, 0, 1, 1)
       L_layout.addWidget(btn1, 1, 0, 1, 1)
       R_layout.addWidget(textedit)

       splitter1 = QSplitter(Qt.Horizontal,frameShape=QFrame.StyledPanel,frameShadow=QFrame.Plain)
       splitter1.addWidget(L_widgets)
       splitter1.addWidget(R_widgets)
       splitter1.setStretchFactor(1,1)

       splitter2 = QSplitter(Qt.Vertical)
       splitter2.addWidget(splitter1)
       splitter2.addWidget(bottom)

       hbox.addWidget(splitter2)

       self.setLayout(hbox)
       #QApplication.setStyle(QStyleFactory.create('Cleanlooks'))

       self.setGeometry(300, 300, 300, 200)
       self.setWindowTitle('QSplitter demo')
       self.show()

def main():
    app = QApplication(sys.argv)
    ex = Example()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()
Lester_wu
  • 151
  • 5
  • My apologies, but I think this is addressing a different concern. I've added an additional picture above showing the widget visual glitch that I'm describing, whereby `splitter1` is not rendering its background fully like `splitter2` is. – ees Dec 28 '18 at 16:00
  • I think you draw border for splitter1 and bottom, so it seems split by QSplitter but actually that's you draw the border. And topleft and btn1 and textedit are inside splitter1's border, so it looks like not split by QSplitter. But, actually, they all split well by QSplitter. Furthermore, there is a splitter handle to split widgets, you can set the background-color for it, and then you can see obvious border to split widgets. Please refer to this [link](https://stackoverflow.com/questions/6832499/qsplitter-show-a-divider-or-a-margin-between-the-two-widgets) – Lester_wu Dec 28 '18 at 17:19
  • Thanks for the suggestion. However, none of the Stylesheets really do what I need... and after further research, this appears to be a mac os bug. In linux, the `splitter1` bar appears perfectly fine (as in, matching the look of `splitter2`). – ees Dec 29 '18 at 21:15
  • @ees I recommend using PyQt5, PyQt4 is deprecated so the bugs will probably never be fixed and I would only recommend using it if you are going to keep software. In contrast probably in PyQt5 the bug you indicate no longer exists. – eyllanesc Dec 29 '18 at 21:33