PySide6-How to adjust the widgets in a Qsplitter?
-
I have code:
from PySide6.QtWidgets import QWidget, QVBoxLayout, QSplitter, QApplication, QTextBrowser from PySide6.QtCore import Qt import sys class E1(QWidget): def __init__(self): super().__init__() self.layout = QVBoxLayout(self) self.top = QTextBrowser(self) self.bottom = QTextBrowser(self) splitter2 = QSplitter(Qt.Vertical) splitter2.addWidget(self.top) splitter2.addWidget(self.bottom) self.layout.addWidget(splitter2) self.layout.setSpacing(30) self.layout.setStretch(1, 1) self.setGeometry(100, 100, 800, 600) class E2(QWidget): def __init__(self): super().__init__() self.layout = QVBoxLayout(self) self.top = QTextBrowser(self) self.bottom = QTextBrowser(self) self.layout.addWidget(self.top) self.layout.addWidget(self.bottom) self.layout.setSpacing(30) self.layout.setStretch(1, 1) self.setGeometry(100, 100, 800, 600) if __name__ == '__main__': app = QApplication(sys.argv) e1 = E1() e1.show() e2 = E2() e2.show() sys.exit(app.exec())
The two UIs are different.
From the left UI, code which can adjust the widgets in a layout likeself.layout.setSpacing(30)
seems to become useless when widgets are in aQsplitter
.
Is there a way for the widgets in a Qsplitter to be adjusted freely like those in a layout does? -
Hi,
In the case of the splitter, you have only one widget in the layout: the splitter itself.
-
It is not clear for me what behaviour you want to achieve.
Do you want to have a splitter with height = 30? (i.e. so wide splitter). Or is it something else... -
@StarterKit I want to stretch a widget (e.g. a text browser) up or down, and at the same time I want to adjust the widget freely in a splitter just like a widget in a QLayout does. In the above picture, in the left window, the text browser can stretch up or down, but I can't assign a specified layout. In the right window, I can set preferred layout, but the text browsers are fixed size.
-
It looks like you want to put your editor in a layout in a "container" widget and then put that container widget in the splitter.
-
@SGaist
When my cursor is on the edge of a textbroswer, it will become a arrow-like style and I can drag the text browser up and down. But the problem is, I can't set a preferred initial layout for the two text browsers. I can't make the left window lool like the right window. -
@feiyuhuahuo , pardon, but it is still not fully clear abot what you want to achieve at the end...
Did I get it right that you need:- 2 separated text editors, one above another;
- wide empty space between 2 editors, i.e. for example constatly have 2 editors separated by 100 pixels;
- you want to adjust size of text editors - i.e. decrease one and increase another keeping them separated by wide fixed area.
Is it so? Or I got something wrong?...
-
@StarterKit
Yes, you almost get it right. Let me be specific.
Actually, I have a custom UI. You can see from the below gif that, the ui is good alignment at the first time it is showed. But the right column can not drag up or down.
So I usedQsplitter
to achieve this function (show in the below gif). But the code logic is, the label 'dd', textbrowser(top), label 'aa', textbrowser(bottom) are in a same Qsplitter, and then the Qsplitter is put in a QHboxLayout. Because of this, I can't keep them good alignment at the first time they are showed. The format which I designed inQtDesigner
becomes useless and I also can't use QLayout related code to adjust the alignment.
At the end, my requirement is that I want to drag the right column up and down and keep the alignment good at the first time the window is showed. -
@feiyuhuahuo ok, I think I understood you.
But before giving any proposals I would like to check my understading.
So, the problem is: when you put a splitter in right column it takes extra space. And there is nothing in left column that would be aligned with the splitter. It makes left column a bit disconnected (by some pixels) from right clumn.
Right?So, you need something in your left column to occupy exactly the same space as splitter does in the right column?
-
@StarterKit
This is the initial window after I callingshow()
. You can see that the purple line and the yellow line are misalignment, they are not horizontal alignment. So as the red line and the blue line. I don't know how to adjust the format of the widgets in the right column. All the widgets of the right column are in a QSplitter. They can not be adjusted freely like those in a QHBoxLayout does. After calling show of the window, without any operation, I want the right column to be the same format as that in the top gif in my last reply.
-
@feiyuhuahuo , ok, try this example - does it look like what you need?
from PySide2.QtWidgets import QApplication, QLabel, QHBoxLayout, QVBoxLayout, QTextEdit, QWidget, QFrame, QSplitter from PySide2.QtCore import Qt, QMargins class ExampleWindow(QWidget): def __init__(self): super().__init__() # Split window into left and right part self.h_layout = QHBoxLayout() self.setLayout(self.h_layout) # Create Left part self.left_frame = QFrame() self.h_layout.addWidget(self.left_frame) self.v_layout_left = QVBoxLayout() # Arrange left part vertically self.left_frame.setLayout(self.v_layout_left) # Build left part of two frames - left_top and left_bottom, both with vertical layout self.left_top = QFrame() self.v_layout_left.addWidget(self.left_top) self.left_top_layout = QVBoxLayout() self.left_top.setLayout(self.left_top_layout) self.left_top_layout.setContentsMargins(QMargins(0, 0, 0, 0)) self.left_top_layout.addWidget(QLabel(text="AA")) # Add widgets to left top frame self.left_top_layout.addWidget(QTextEdit()) self.left_top_layout.addWidget(QLabel(text="BB")) self.left_top_layout.addWidget(QTextEdit()) self.left_bottom = QFrame() self.left_bottom_layout = QVBoxLayout() self.left_bottom_layout.setContentsMargins(QMargins(0, 0, 0, 0)) self.v_layout_left.addWidget(self.left_bottom) self.left_bottom.setLayout(self.left_bottom_layout) self.left_bottom_layout.addWidget(QLabel(text="CC")) # Add widgets to left bottom frame self.left_bottom_layout.addWidget(QTextEdit()) # Define a ratio between upper and lower parts self.v_layout_left.setStretchFactor(self.left_top, 2) self.v_layout_left.setStretchFactor(self.left_bottom, 1) # Create right part self.right_frame = QFrame() self.h_layout.addWidget(self.right_frame) self.v_layout_right = QVBoxLayout() # Arrange right part vertically self.right_frame.setLayout(self.v_layout_right) self.splitter = QSplitter(Qt.Vertical) # Add splitter to the right part self.v_layout_right.addWidget(self.splitter) self.right_top = QFrame() self.right_top_layout = QVBoxLayout() self.right_top_layout.setContentsMargins(QMargins(0, 0, 0, 0)) self.splitter.addWidget(self.right_top) self.right_top.setLayout(self.right_top_layout) self.right_top_layout.addWidget(QLabel(text="DD")) # Add widgets to right top frame self.right_top_layout.addWidget(QTextEdit()) self.right_bottom = QFrame() self.right_bottom_layout = QVBoxLayout() self.right_bottom_layout.setContentsMargins(QMargins(0, 0, 0, 0)) self.splitter.addWidget(self.right_bottom) self.right_bottom.setLayout(self.right_bottom_layout) self.right_bottom_layout.addWidget(QLabel(text="EE")) # Add widgets to right bottom frame self.right_bottom_layout.addWidget(QTextEdit()) # Define a ratio between upper and lower parts self.splitter.setStretchFactor(0, 2) self.splitter.setStretchFactor(1, 1) if __name__ == '__main__': app = QApplication() wnd = ExampleWindow() wnd.resize(800, 600) wnd.show() app.exec_()
-
class ExampleWindow(QWidget): def __init__(self): super().__init__() # Split window into left and right part self.h_layout = QHBoxLayout() self.setLayout(self.h_layout) self.left_top_layout = QVBoxLayout() self.left_top_layout.setContentsMargins(QMargins(0, 0, 0, 0)) self.left_top_layout.addWidget(QLabel(text="AA")) # Add widgets to left top frame self.left_top_layout.addWidget(QTextBrowser()) self.left_top_layout.addWidget(QLabel(text="BB")) self.left_top_layout.addWidget(QTextBrowser()) self.left_top_layout.addWidget(QLabel(text="CC")) # Add widgets to left bottom frame self.left_top_layout.addWidget(QTextBrowser()) self.h_layout.addLayout(self.left_top_layout) self.splitter = QSplitter(Qt.Vertical) # Add splitter to the right part self.splitter.addWidget(QLabel(text="DD")) self.splitter.addWidget(QTextBrowser()) self.splitter.addWidget(QLabel(text="EE")) self.splitter.addWidget(QTextBrowser()) # Define a ratio between upper and lower parts self.splitter.setStretchFactor(0, 0) self.splitter.setStretchFactor(1, 108) self.splitter.setStretchFactor(2, 0) self.splitter.setStretchFactor(3, 50) self.rl = QVBoxLayout() self.rl.addWidget(self.splitter) self.h_layout.addLayout(self.rl) if __name__ == '__main__': app = QApplication() wnd = ExampleWindow() wnd.resize(800, 600) wnd.show() app.exec()
@StarterKit Thanks, I splified your code. The
self.splitter.setStretchFactor
is really helpful. I can make my UI looks better now. But I think it's better forQsplitter
to supportsetSpacing
function either likeQLayout
does. In my above code, if I set a spacing forself.left_top_layout
, then the left column and the right column will not be horizontal alignment. Besides, willQtDesigner
supportQsplitter
? It's often used and will be convenient if we can edit it inQtDesigner
. -
@feiyuhuahuo said in PySide6-How to adjust the widgets in a Qsplitter?:
Thanks, I splified your code.
You are welcome. I didn't know exactly your goal so I did just a fast and dirty draft to illustrate an option. You may adjust it freely to your exact needs.
@feiyuhuahuo said in PySide6-How to adjust the widgets in a Qsplitter?:
Besides, will QtDesigner support Qsplitter?
Yes, it supports:
- Select widgets with help of Ctrl and left mouse key
- Right mouse click, choose menu item Layout and make appropriated split selection.