繁体   English   中英

PyQt5 更新/替换 QScrollArea 内的 QTableWidget

[英]PyQt5 update/replace a QTableWidget inside a QScrollArea

我对基于 Qt5 的 python GUI 有疑问。 我有一个元素到 select 一个路径,然后是一个 QScrollArea ,其中 QTable 与目录的文件一起显示。 This works fine when the directory is selected the first time, but when a new directory is selected the table is not updated, I get the following error: "QLayout: Attempting to add QLayout "" to QScrollArea "", which already has a layout "

到目前为止,我知道我必须删除父级,但我没有找到解决方案(对不起,我是 Qt 新手)。 任何帮助表示赞赏。

谢谢,亚历克斯

这是工作示例:

import sys
import tempfile
import time
import ntpath
import os
from os import listdir
from os.path import isfile, join
import platform
import subprocess
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QPushButton, QScrollArea, QVBoxLayout, QCheckBox, QInputDialog, QLineEdit, QComboBox, QMessageBox, QWidget, QDialog
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtWidgets import QTableWidget,QTableWidgetItem, QLabel
from PyQt5.QtGui import QPixmap, QIcon


LastStateRole = QtCore.Qt.UserRole

class Ui_brows(object):
    def createFileTable(self, fileList):
        self.fileTable = QTableWidget()
        self.fileTable.setRowCount(len(fileList))
        self.fileTable.setColumnCount(4)
        self.fileTable.setHorizontalHeaderLabels(['Include', 'Target','Name', 'Path'])
        for l in range (len(fileList)):
            item = QtWidgets.QTableWidgetItem()
            item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
            item.setCheckState(QtCore.Qt.Checked)
            item.setData(LastStateRole, item.checkState())
            self.fileTable.setItem(l,0,item)
            self.fileTable.setItem(l,1,QTableWidgetItem(""))
            nameString = ntpath.basename(fileList[l])
            self.fileTable.setItem(l,2,QTableWidgetItem(nameString))
            self.fileTable.setItem(l,3,QTableWidgetItem(fileList[l]))
        self.fileTable.setColumnWidth(0,40)
        self.fileTable.setColumnWidth(0,80)    
        self.layout = QVBoxLayout(self.scrollArea)
        self.layout.addWidget(self.fileTable)

    def _open_file_dialog(self):
        directory = str(QtWidgets.QFileDialog.getExistingDirectory())
        fileList = []
        for f in listdir(directory):
            fileList.append(f)
        self.createFileTable(fileList)

    def setupUi(self, brows):
        brows.setObjectName("MyApp")
        brows.resize(900, 600)
        
        #### line 1
        self.toolButtonOpenDialog = QtWidgets.QToolButton(brows)
        self.toolButtonOpenDialog.setGeometry(QtCore.QRect(310, 10, 35, 19))
        self.toolButtonOpenDialog.setObjectName("toolButtonOpenDialog")
        self.toolButtonOpenDialog.clicked.connect(self._open_file_dialog)

        self.importPath = QtWidgets.QLineEdit(brows)
        self.importPath.setEnabled(False)
        self.importPath.setGeometry(QtCore.QRect(110, 10, 191, 20))
        self.importPath.setObjectName("importPath")
        
        self.label1 = QtWidgets.QLabel(brows)
        self.label1.setText('Folder to scan')
        self.label1.setGeometry(QtCore.QRect(10,10,90,20))
        self.label1.setObjectName("Label1")
        
        self.label11 = QtWidgets.QLabel(brows)
        self.label11.setText('Scan Depth')
        self.label11.setGeometry(QtCore.QRect(370,10,90,20))
        self.label11.setObjectName("Label11")
        
        self.folderDepth = QComboBox(brows)
        self.folderDepth.addItems(['1','2','3','>3'])
        self.folderDepth.setGeometry(QtCore.QRect(450,8,50,25))
        self.folderDepth.setObjectName("FolderDepth")
        
        #### line 2
        self.label2 = QtWidgets.QLabel(brows)
        self.label2.setText('Local mount')
        self.label2.setGeometry(QtCore.QRect(10,50,90,20))
        self.label2.setObjectName("Label2")
        
        self.localMount = QtWidgets.QLineEdit(brows)
        self.localMount.setEnabled(True)
        self.localMount.setGeometry(QtCore.QRect(100, 50, 90, 20))
        self.localMount.setObjectName("localMount")
        
        self.label3 = QtWidgets.QLabel(brows)
        self.label3.setText('Remote mount')
        self.label3.setGeometry(QtCore.QRect(230,50,90,20))
        self.label3.setObjectName("Label3")
        
        self.remoteMount = QtWidgets.QLineEdit(brows)
        self.remoteMount.setEnabled(True)
        self.remoteMount.setGeometry(QtCore.QRect(330, 50, 80, 20))
        self.remoteMount.setObjectName("remoteMount")
        
        #### line 3
        self.scrollArea = QScrollArea(brows)
        self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setGeometry(QtCore.QRect(10, 100, 880, 400))

        self.retranslateUi(brows)
        QtCore.QMetaObject.connectSlotsByName(brows)

    def retranslateUi(self, brows):
        _translate = QtCore.QCoreApplication.translate
        brows.setWindowTitle(_translate("myApp", "MyApp"))
        self.toolButtonOpenDialog.setText(_translate("brows", "..."))

    
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    brows = QtWidgets.QDialog()
    ui = Ui_brows()
    ui.setupUi(brows)
    brows.show()

    sys.exit(app.exec_())

QTableWidget 里面已经有了滚动区域,不需要再创建一个。 请参阅下面的代码。

如果您仍想在表格之外放置额外的滚动区域。 您可以查看示例如何在结构中正确使用一个:

Top_Level_Widget->Top_Level_Layout
Second_Level_QScrollArea
Third_Level_Widget_For_QScrollArea->Third_Level_Layout_of_ScrollArea_Widget
Fourth_Level_Contents_Inside。

https://github.com/baoboa/pyqt5/blob/master/examples/draganddrop/delayedencoding/delayedencoding.py

import sys
import tempfile
import time
import ntpath
import os
from os import listdir
from os.path import isfile, join
import platform
import subprocess
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QPushButton, QScrollArea, QVBoxLayout, QCheckBox, QInputDialog, QLineEdit, QComboBox, QMessageBox, QWidget, QDialog
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtWidgets import QTableWidget,QTableWidgetItem, QLabel
from PyQt5.QtGui import QPixmap, QIcon


LastStateRole = QtCore.Qt.UserRole

class Ui_brows(object):
    def createFileTable(self, fileList):
        self.fileTable = QTableWidget()
        self.fileTable.setRowCount(len(fileList))
        self.fileTable.setColumnCount(4)
        self.fileTable.setHorizontalHeaderLabels(['Include', 'Target','Name', 'Path'])
        for l in range (len(fileList)):
            item = QtWidgets.QTableWidgetItem()
            item.setFlags(QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
            item.setCheckState(QtCore.Qt.Checked)
            item.setData(LastStateRole, item.checkState())
            self.fileTable.setItem(l,0,item)
            self.fileTable.setItem(l,1,QTableWidgetItem(""))
            nameString = ntpath.basename(fileList[l])
            self.fileTable.setItem(l,2,QTableWidgetItem(nameString))
            self.fileTable.setItem(l,3,QTableWidgetItem(fileList[l]))
        self.fileTable.setColumnWidth(0,40)
        self.fileTable.setColumnWidth(0,80)
        if self.table_place_holder_layout.count():
            self.table_place_holder_layout.takeAt(0).widget().deleteLater()
        self.table_place_holder_layout.addWidget(self.fileTable)

    def _open_file_dialog(self):
        directory = str(QtWidgets.QFileDialog.getExistingDirectory())
        if not directory:
            return
        fileList = []
        for f in listdir(directory):
            fileList.append(f)
        self.createFileTable(fileList)

    def setupUi(self, brows):
        brows.setObjectName("MyApp")
        brows.resize(900, 600)

        #### line 1
        self.toolButtonOpenDialog = QtWidgets.QToolButton(brows)
        self.toolButtonOpenDialog.setGeometry(QtCore.QRect(310, 10, 35, 19))
        self.toolButtonOpenDialog.setObjectName("toolButtonOpenDialog")
        self.toolButtonOpenDialog.clicked.connect(self._open_file_dialog)

        self.importPath = QtWidgets.QLineEdit(brows)
        self.importPath.setEnabled(False)
        self.importPath.setGeometry(QtCore.QRect(110, 10, 191, 20))
        self.importPath.setObjectName("importPath")

        self.label1 = QtWidgets.QLabel(brows)
        self.label1.setText('Folder to scan')
        self.label1.setGeometry(QtCore.QRect(10,10,90,20))
        self.label1.setObjectName("Label1")

        self.label11 = QtWidgets.QLabel(brows)
        self.label11.setText('Scan Depth')
        self.label11.setGeometry(QtCore.QRect(370,10,90,20))
        self.label11.setObjectName("Label11")

        self.folderDepth = QComboBox(brows)
        self.folderDepth.addItems(['1','2','3','>3'])
        self.folderDepth.setGeometry(QtCore.QRect(450,8,50,25))
        self.folderDepth.setObjectName("FolderDepth")

        #### line 2
        self.label2 = QtWidgets.QLabel(brows)
        self.label2.setText('Local mount')
        self.label2.setGeometry(QtCore.QRect(10,50,90,20))
        self.label2.setObjectName("Label2")

        self.localMount = QtWidgets.QLineEdit(brows)
        self.localMount.setEnabled(True)
        self.localMount.setGeometry(QtCore.QRect(100, 50, 90, 20))
        self.localMount.setObjectName("localMount")

        self.label3 = QtWidgets.QLabel(brows)
        self.label3.setText('Remote mount')
        self.label3.setGeometry(QtCore.QRect(230,50,90,20))
        self.label3.setObjectName("Label3")

        self.remoteMount = QtWidgets.QLineEdit(brows)
        self.remoteMount.setEnabled(True)
        self.remoteMount.setGeometry(QtCore.QRect(330, 50, 80, 20))
        self.remoteMount.setObjectName("remoteMount")

        #### line 3
        self.table_place_holder = QtWidgets.QWidget(brows)
        self.table_place_holder_layout = QVBoxLayout(self.table_place_holder)
        # self.scrollArea = QScrollArea(brows)
        # self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        # self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        # self.scrollArea.setWidgetResizable(True)
        # self.scrollArea.setGeometry(QtCore.QRect(10, 100, 880, 400))
        self.table_place_holder.setGeometry(QtCore.QRect(10, 100, 880, 400))

        self.retranslateUi(brows)
        QtCore.QMetaObject.connectSlotsByName(brows)

    def retranslateUi(self, brows):
        _translate = QtCore.QCoreApplication.translate
        brows.setWindowTitle(_translate("myApp", "MyApp"))
        self.toolButtonOpenDialog.setText(_translate("brows", "..."))


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    brows = QtWidgets.QDialog()
    ui = Ui_brows()
    ui.setupUi(brows)
    brows.show()

    sys.exit(app.exec_())

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM