PyQt - переключение между двумя виджетами без изменения размера qsplitter - PullRequest
0 голосов
/ 03 декабря 2018

Я пытаюсь переключить контейнер разделителя между двумя виджетами, сохраняя фактический размер разделителя.Для этого я использую 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 Ответ

0 голосов
/ 03 декабря 2018

Вы ищете 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().Здесь есть множество вопросов, касающихся этой темы.Просто найдите heightForWidth .

...