2

我想要做的是将拆分器添加到 QGridLayout 以便使用鼠标调整布局大小。因此,例如:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class SurfViewer(QMainWindow):
    def __init__(self, parent=None):
        super(SurfViewer, self).__init__()
        self.parent = parent
        self.setFixedWidth(300)
        self.setFixedHeight(100)

        self.wid = QWidget()
        self.setCentralWidget(self.wid)

        self.grid = QGridLayout()

        l_a = QLabel('A')
        l_b = QLabel('B')
        l_c = QLabel('C')
        l_d = QLabel('D')
        l_e = QLabel('E')
        l_f = QLabel('F')
        l_g = QLabel('G')
        l_h = QLabel('H')
        l_i = QLabel('I')
        self.grid.addWidget(l_a, 0, 0)
        self.grid.addWidget(l_b, 0, 1)
        self.grid.addWidget(l_c, 0, 2)
        self.grid.addWidget(l_d, 1, 0)
        self.grid.addWidget(l_e, 1, 1)
        self.grid.addWidget(l_f, 1, 2)
        self.grid.addWidget(l_g, 2, 0)
        self.grid.addWidget(l_h, 2, 1)
        self.grid.addWidget(l_i, 2, 2)
        self.wid.setLayout(self.grid)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = SurfViewer(app)
    ex.setWindowTitle('window')
    ex.show()
    sys.exit(app.exec_( ))

我明白了:

在此处输入图像描述

我想要的不是彩色线,而是可以垂直(对于绿线)和水平(对于红线)单击并拖动网格边框。

我直接用QSplitter尝试了一些东西,但我最终得到:

在此处输入图像描述

水平分割还可以,但垂直分割不再对齐:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class SurfViewer(QMainWindow):
    def __init__(self, parent=None):
        super(SurfViewer, self).__init__()
        self.parent = parent
        self.setFixedWidth(300)
        self.setFixedHeight(100)

        self.wid = QWidget()
        self.setCentralWidget(self.wid)

        # self.grid = QGridLayout()
        self.globallayout = QVBoxLayout()
        self.split_V = QSplitter(Qt.Vertical)

        l_a = QLabel('A')
        l_b = QLabel('B')
        l_c = QLabel('C')
        l_d = QLabel('D')
        l_e = QLabel('E')
        l_f = QLabel('F')
        l_g = QLabel('G')
        l_h = QLabel('H')
        l_i = QLabel('I')
        split_H = QSplitter(Qt.Horizontal)
        split_H.addWidget(l_a)
        split_H.addWidget(l_b)
        split_H.addWidget(l_c)
        self.split_V.addWidget(split_H)

        split_H = QSplitter(Qt.Horizontal)
        split_H.addWidget(l_d)
        split_H.addWidget(l_e)
        split_H.addWidget(l_f)
        self.split_V.addWidget(split_H)

        split_H = QSplitter(Qt.Horizontal)
        split_H.addWidget(l_g)
        split_H.addWidget(l_h)
        split_H.addWidget(l_i)
        self.split_V.addWidget(split_H)

        self.globallayout.addWidget(self.split_V)

        self.wid.setLayout(self.globallayout)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = SurfViewer(app)
    ex.setWindowTitle('window')
    ex.show()
    sys.exit(app.exec_( ))

更新

我想我几乎找到了一个使用函数的解决方案,这样每当垂直分割发生变化时,它就会重新对齐它们:

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys

class SurfViewer(QMainWindow):
    def __init__(self, parent=None):
        super(SurfViewer, self).__init__()
        self.parent = parent
        self.setFixedWidth(300)
        self.setFixedHeight(100)

        self.wid = QWidget()
        self.setCentralWidget(self.wid)

        # self.grid = QGridLayout()
        self.globallayout = QVBoxLayout()
        self.split_V = QSplitter(Qt.Vertical)

        l_a = QLabel('A')
        l_b = QLabel('B')
        l_c = QLabel('C')
        l_d = QLabel('D')
        l_e = QLabel('E')
        l_f = QLabel('F')
        l_g = QLabel('G')
        l_h = QLabel('H')
        l_i = QLabel('I')
        self.split_H1 = QSplitter(Qt.Horizontal)
        self.split_H1.addWidget(l_a)
        self.split_H1.addWidget(l_b)
        self.split_H1.addWidget(l_c)
        self.split_V.addWidget(self.split_H1)

        self.split_H2 = QSplitter(Qt.Horizontal)
        self.split_H2.addWidget(l_d)
        self.split_H2.addWidget(l_e)
        self.split_H2.addWidget(l_f)
        self.split_V.addWidget(self.split_H2)

        self.split_H3 = QSplitter(Qt.Horizontal)
        self.split_H3.addWidget(l_g)
        self.split_H3.addWidget(l_h)
        self.split_H3.addWidget(l_i)
        self.split_V.addWidget(self.split_H3)

        self.globallayout.addWidget(self.split_V)

        self.wid.setLayout(self.globallayout)

        self.split_H1.splitterMoved.connect(self.moveSplitter)
        self.split_H2.splitterMoved.connect(self.moveSplitter)
        self.split_H3.splitterMoved.connect(self.moveSplitter)

        # self.split_H1.splitterMoved
        # self.moveSplitter(0,self.split_H1.at )

    def moveSplitter( self, index, pos ):
        # splt = self._spltA if self.sender() == self._spltB else self._spltB
        self.split_H1.blockSignals(True)
        self.split_H2.blockSignals(True)
        self.split_H3.blockSignals(True)
        self.split_H1.moveSplitter(index, pos)
        self.split_H2.moveSplitter(index, pos)
        self.split_H3.moveSplitter(index, pos)
        self.split_H1.blockSignals(False)
        self.split_H2.blockSignals(False)
        self.split_H3.blockSignals(False)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = SurfViewer(app)
    ex.setWindowTitle('window')
    ex.show()
    sys.exit(app.exec_( ))

但是,我在开始时仍然遇到问题 - 对齐不正确:

在此处输入图像描述

我不知道如何调用函数moveSplitter中的__init__

4

1 回答 1

3

似乎直接调用moveSplitter(这是一种受保护的方法)可能会有问题。在 Linux 上使用 Qt-5.10.1 和 PyQt-5.10.1,我发现在__init__. Qt 提供了一种公共方法来更改拆分器的位置可能是有充分理由setSizes的,因此最好选择它而不是moveSplitter.

考虑到这一点,我得出了以下实现:

class SurfViewer(QMainWindow):
    def __init__(self, parent=None):
        ...
        self.split_H1.splitterMoved.connect(self.moveSplitter)
        self.split_H2.splitterMoved.connect(self.moveSplitter)
        self.split_H3.splitterMoved.connect(self.moveSplitter)

        QTimer.singleShot(0, lambda: self.split_H1.splitterMoved.emit(0, 0))

    def moveSplitter(self, index, pos):
        sizes = self.sender().sizes()
        for index in range(self.split_V.count()):
            self.split_V.widget(index).setSizes(sizes)

需要单次计时器,因为在某些平台上,窗口的几何形状在屏幕上显示之前可能未完全初始化。并且注意setSizes不会触发splitterMoved,所以使用的时候不需要阻塞信号。

于 2018-03-07T17:35:55.250 回答