1

我想使用 QSplitter 在两侧拆分 MainWindow。在左侧我想要一个包含文件夹视图的布局,在右侧我将绘制一些东西的另一个布局。但我只能在 QSplitter 上添加小部件,而布局不是小部件。我发现的唯一类似的问题是:

http://www.qtcentre.org/threads/16856-QSplitter-multiple-layouts-how https://forum.qt.io/topic/8197/solved-qsplitter-and-qvboxlayout-problem

所以,根据上面的链接,我的计划是创建两个布局,然后将它们添加到两个QWidgets(使用setLayout),然后将这些QWidgets添加到QSplitter(使用addWidget)。我试图将其应用于我的代码,但不幸的是,当我将布局添加到小部件时,什么都没有显示!

还有其他方法可以实现我想要的吗?我误解了答案吗?

这是代码。为了使代码更简单,我只向您发送文件夹视图布局。另外,我对 pyqt 和面向对象编程完全陌生,因此欢迎对如何改进它提出任何建议!

提前致谢!

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

class Window(QMainWindow):

    def __init__(self, parent=None):

        super(Window, self).__init__(parent)
        self.UI()

    def UI(self):

        self.central_widget = QStackedWidget()
        self.setCentralWidget(self.central_widget)

        self.statusBar().showMessage("Ready")

        page1 = FirstWidget(self)
        page1.visualize_btn.clicked.connect(self.P_2)
        self.central_widget.addWidget(page1)        

        self.setGeometry(10, 10, 800, 500)    #All three methods have been inherited from the QWidget class.
        self.showMaximized()
        self.setWindowTitle('PTV')
        self.setWindowIcon(QIcon('tuc_logo.png'))

    def P_2(self):

        page2 = VisualizeWidget(self)
        self.central_widget.addWidget(page2)
        self.central_widget.setCurrentWidget(page2)


class FirstWidget(QWidget):

    def __init__(self, parent=None):
        super(FirstWidget, self).__init__(parent)
        self.buttons()

    def buttons(self):

        self.btn2 = QPushButton("Visualize")
        self.buttonsLayout = QVBoxLayout() 
        self.buttonsLayout.addWidget(self.btn2)
        self.visualize_btn = self.btn2        
        self.setLayout(self.buttonsLayout)


class VisualizeWidget(QWidget):

    def __init__(self, parent=None):
        super(VisualizeWidget, self).__init__(parent)


        self.dirmodel = QFileSystemModel()        
        self.dirmodel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)    # Don't show files, just folders

        self.folder_view = QTreeView(parent=self);
        self.folder_view.setModel(self.dirmodel)
        self.folder_view.clicked[QModelIndex].connect(self.clicked)

        self.now_layout = QVBoxLayout()
        self.now_layout.addWidget(self.folder_view)

        #self.setLayout(self.now_layout)

        #HERE is where I'm trying to add the layout to the widget. 
        self.left_widget = QWidget()
        self.left_widget.setLayout(self.now_layout)            


    def set_path(self):
        self.dirmodel.setRootPath("")

    def clicked(self, index):
        index = self.selectionModel.currentIndex()
        dir_path = self.dirmodel.filePath(index)

        self.filemodel.setRootPath(dir_path)
        self.file_view.setRootIndex(self.filemodel.index(dir_path))          

def main():
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    app.exec_()

if __name__ == '__main__':
    sys.exit(main()) 
4

2 回答 2

1

我实际上还没有理解我做错了什么,但我正在发布一个工作代码,以防它在未来帮助其他人。

现在这两个布局被一个 QSplitter 分割。

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

class Window(QMainWindow):

    def __init__(self, parent=None):

        super(Window, self).__init__(parent)
        self.UI()

    def UI(self):

        self.central_widget = QStackedWidget()
        self.setCentralWidget(self.central_widget)

        self.statusBar().showMessage("Ready")

        page1 = FirstWidget(self)
        page1.visualize_btn.clicked.connect(self.P_2)
        self.central_widget.addWidget(page1)        

        self.setGeometry(10, 10, 800, 500)    #All three methods have been inherited from the QWidget class.
        self.showMaximized()
        self.setWindowTitle('PTV')
        self.setWindowIcon(QIcon('tuc_logo.png'))

    def P_2(self):

        page2 = VisualizeWidget(self)
        self.central_widget.addWidget(page2)
        self.central_widget.setCurrentWidget(page2)


class FirstWidget(QWidget):

    def __init__(self, parent=None):
        super(FirstWidget, self).__init__(parent)
        self.buttons()

    def buttons(self):

        self.btn2 = QPushButton("Visualize")
        self.buttonsLayout = QVBoxLayout() 
        self.buttonsLayout.addWidget(self.btn2)
        self.visualize_btn = self.btn2        
        self.setLayout(self.buttonsLayout)


class VisualizeWidget(QWidget):

    def __init__(self, parent=None):
        super(VisualizeWidget, self).__init__(parent)


        #Creation of the left layout
        self.dirmodel = QFileSystemModel()        
        self.dirmodel.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs)    # Don't show files, just folders

        self.folder_view = QTreeView(parent=self);
        self.folder_view.setModel(self.dirmodel)
        self.folder_view.clicked[QModelIndex].connect(self.clicked)

        self.selectionModel = self.folder_view.selectionModel()

        self.now_layout = QVBoxLayout()
        self.now_layout.addWidget(self.folder_view)


        self.left_widget = QWidget()
        self.left_widget.setLayout(self.now_layout)


        #Creation of the right layout
        #self.right_widget = QTextEdit();

        self.btn1 = QPushButton('btn1')

        self.right_layout = QVBoxLayout()
        self.right_layout.addWidget(self.btn1)

        self.right_widget = QWidget()
        self.right_widget.setLayout(self.right_layout)




        splitter_filebrowser = QSplitter(Qt.Horizontal)
        splitter_filebrowser.addWidget(self.left_widget)
        splitter_filebrowser.addWidget(self.right_widget)
        splitter_filebrowser.setStretchFactor(1, 1)

        hbox = QHBoxLayout(self)
        hbox.addWidget(splitter_filebrowser)

        self.setLayout(hbox)



    def set_path(self):
        self.dirmodel.setRootPath("")

    def clicked(self, index):
        index = self.selectionModel.currentIndex()
        dir_path = self.dirmodel.filePath(index)

        self.filemodel.setRootPath(dir_path)
        self.file_view.setRootIndex(self.filemodel.index(dir_path))          

def main():
    app = QApplication(sys.argv)
    win = Window()
    win.show()
    app.exec_()

if __name__ == '__main__':
    sys.exit(main()) 
于 2017-03-20T13:00:22.363 回答
0

我冒昧地清理了@A.Dew 对其最小通用形式的回答。

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QApplication, QSplitter, QWidget, QVBoxLayout, QMainWindow, QGridLayout, QLayout
from PyQt5.QtWidgets import QToolBar, QPushButton, QLabel


class QPanedWidget(QWidget):

    def __init__(self, first_pane: QWidget, second_pane: QWidget, orientation: Qt.Orientation = Qt.Horizontal):
        super().__init__()

        left_pane = first_pane
        right_pane = second_pane

        splitter = QSplitter(orientation)
        splitter.addWidget(left_pane)
        splitter.addWidget(right_pane)

        layout = QGridLayout(self)
        layout.addWidget(splitter)
        self.setLayout(layout)


# noinspection PyMethodMayBeStatic
class SplitWindow(QMainWindow):

    def __init__(self, parent=None):
        super(SplitWindow, self).__init__(parent)
        self.statusBar().showMessage("Ready")
        self.resize(800, 600)
        self.setCentralWidget(self.build_layout())

    def build_layout(self):
        return QPanedWidget(
            self.create_pane(self.create_pane_content('left')),
            self.create_pane(self.create_pane_content('right')),
            Qt.Horizontal  # This is optional, defaults to horizontal
        )

    def create_pane(self, content: QLayout) -> QWidget:
        # Container widget for pane layout
        pane_layout_container = QWidget()
        pane_layout_container.setLayout(content)
        return pane_layout_container

    def create_pane_content(self, identifier) -> QLayout:
        content = QVBoxLayout()  # Layout widget for pane content

        # FROM HERE you create your own content

        toolbar = QToolBar()
        toolbar.addWidget(QPushButton("Do Something"))
        content.addWidget(toolbar)  # Don't forget this! ^_^

        label = QLabel(identifier)
        label.setAutoFillBackground(True)
        p = label.palette()
        p.setColor(label.backgroundRole(), Qt.lightGray)
        label.setPalette(p)
        label.setAlignment(Qt.AlignCenter)

        content.addWidget(label)  # Don't forget this! ^_^

        # UNTIL HERE you populate your content

        return content


if __name__ == '__main__':
    app = QApplication([])
    win = SplitWindow()
    win.show()
    app.exec_()
于 2020-12-06T11:14:22.267 回答