PyQt - переключение между двумя виджетами без изменения размера qsplitter
Я пытаюсь переключить контейнер разделителя между двумя виджетами, сохраняя фактический размер разделителя. Для этого я использую QSplitter.sizes (), чтобы прочитать фактический размер, и QSplitter.setSizes () после того, как я переключаю свои виджеты.
Проблема в том, что у меня есть QToolButton, размер которого я изменяю с помощью setFixedSize () в resizeEvent (), и из-за этого, когда я устанавливаю новый размер, он часто не работает.
Я пишу небольшой скрипт, чтобы воспроизвести это: в левой части разделителя у меня есть кнопка для переключения правой части разделителя между двумя классами (которые являются QWidgets).
Немного точности: я хочу, чтобы моя кнопка QToolbutton имела соотношение сторон 1:1.
Вот демо: https://webmshare.com/play/5Bmvn
Итак, вот сценарий:
from PyQt4 import QtGui, QtCore
minSize = 50
maxSize = 350
class mainWindow(QtGui.QWidget):
def __init__(self):
super(mainWindow, self).__init__()
self.layout = QtGui.QVBoxLayout(self)
self.splitter = QtGui.QSplitter(QtCore.Qt.Horizontal, self)
self.splitter.setHandleWidth(20)
self.layout.addWidget(self.splitter)
wgt_left = QtGui.QWidget()
lyt_left = QtGui.QVBoxLayout(wgt_left)
self.btn_toggleSplitter = QtGui.QPushButton('Toggle Button')
self.btn_toggleSplitter.setSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding)
self.btn_toggleSplitter.setCheckable(True)
lyt_left.addWidget(self.btn_toggleSplitter)
self.splitter.addWidget(wgt_left)
self.first = panel('1')
self.second = panel('2')
self.splitter.addWidget(self.first)
self.width = self.first.size()
self.btn_toggleSplitter.clicked.connect(self.ToggleParent)
def ToggleParent(self):
self.sizes = self.splitter.sizes()
if self.btn_toggleSplitter.isChecked() == True:
self.first.setParent(None)
self.splitter.addWidget(self.second)
else :
self.second.setParent(None)
self.splitter.addWidget(self.first)
self.splitter.setSizes(self.sizes)
class panel(QtGui.QWidget):
def __init__(self, text):
super(panel, self).__init__()
lyt_main = QtGui.QVBoxLayout(self)
lyt_icon = QtGui.QHBoxLayout()
self.tbtn_icon = QtGui.QToolButton()
self.tbtn_icon.setText(text)
self.tbtn_icon.setMinimumSize(QtCore.QSize(minSize,minSize))
self.tbtn_icon.setMaximumSize(QtCore.QSize(maxSize,maxSize))
lyt_icon.addWidget(self.tbtn_icon)
lyt_horizontal = QtGui.QHBoxLayout()
lyt_horizontal.addWidget(QtGui.QPushButton('3'))
lyt_horizontal.addWidget(QtGui.QPushButton('4'))
lyt_main.addWidget(QtGui.QLabel('Below me is the QToolButton'))
lyt_main.addLayout(lyt_icon)
lyt_main.addLayout(lyt_horizontal)
lyt_main.addWidget(QtGui.QPlainTextEdit())
def resizeEvent(self, event):
w = panel.size(self).width()
h = panel.size(self).height()
size = min(h, w)-22
if size >= maxSize:
size = maxSize
elif size <= minSize:
size = minSize
self.tbtn_icon.setFixedSize(size, size)
app = QtGui.QApplication([])
window = mainWindow()
window.resize(600,300)
window.show()
app.exec_()
Спасибо
1 ответ
Ты ищешь QtGui.QStackedWidget
, Добавление виджетов к этому на правой стороне вашего сплиттера изменит код вокругself.first
а такжеself.second
Приведу к этому:
self.stack_right = QtGui.QStackedWidget()
self.splitter.addWidget(self.stack_right)
self.first = panel('1')
self.second = panel('2')
self.stack_right.addWidet(self.first)
self.stack_right.addWidget(self.second)
Тогда вашToggleParent
метод:
def ToggleParent(self):
if self.btn_toggleSplitter.isChecked() == True:
self.stack_right.setCurrentWidget(self.second)
else:
self.stack_right.setCurrentWidget(self.first)
Это позволит избежать неловкости кэширования и изменения размера ваших виджетов вручную.
Приложение: масштабирование кнопок инструмента - это действительно отдельный вопрос, но вот совет:
Посмотрите наheightForWidth
настройка макета дляlyt_left
, Это поможет вам сохранить соотношение 1:1 для QToolButton
, В настоящее время у вас есть политика размеров Preferred/Expanding, которая не имеет смысла, если вам нужно соотношение сторон 1:1. Я настоятельно рекомендую это вручную изменить размер кнопки инструмента при обработке события. Вообще звоню setFixedSize
более одного раза на виджете следует рассматривать в качестве последнего средства. Пусть макеты делают работу.
Приложение к приложению: немного поковыряясь (это было давно), возможно, вам придется наследовать отQToolButton
и переопределитьhasHeightForWidth()
а также heightForWidth()
методы. Здесь есть множество вопросов, касающихся этой темы. Просто ищите высоту для ширины.