如何更新/刷新 qTreewidget?

Posted

技术标签:

【中文标题】如何更新/刷新 qTreewidget?【英文标题】:How to update/refresh qTreewidget? 【发布时间】:2016-09-01 19:48:58 【问题描述】:

我有这个小 UI,它列出了给定路径的文本和 python 脚本文件,但是当我尝试用新项目更新或替换列表时,我认为数据被放置在那里,但它们显示为空白。我认为这与不告诉 UI 数据已更新并且必须重绘 UI 有关吗?

这是我的代码:

import os
import platform
import shutil
import subprocess
import sys
import time

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Window(QtGui.QWidget):
    def __init__(self):
        super(Window, self).__init__()

        self.fileListerObject = fileListGenerator(self)

        self.setObjectName(_fromUtf8("Form"))
        self.resize(350, 300)

        mainSizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Fixed)
        mainSizePolicy.setHorizontalStretch(0)
        mainSizePolicy.setVerticalStretch(0)
        mainSizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())

        self.setSizePolicy(mainSizePolicy)
        self.setSizePolicy(mainSizePolicy)

        self.uiName = 'Tree test'
        self.setWindowTitle(self.uiName)

        self.windowElements()

    def windowElements(self):       
        verticalLayout = QtGui.QVBoxLayout(self)
        verticalLayout.setObjectName(_fromUtf8("verticalLayout"))

        self.inputLineEdit = QtGui.QLineEdit(self)
        verticalLayout.addWidget(self.inputLineEdit)

        buttonThing = QtGui.QPushButton(self)
        buttonThing.setText('SET')
        verticalLayout.addWidget(buttonThing)
        self.connect(buttonThing, QtCore.SIGNAL("clicked()"), self.fileListerObject.fileLister)

        self.treeWidget = QtGui.QTreeWidget(self)
        self.treeWidget.setIndentation(5)
        self.treeWidget.setAllColumnsShowFocus(True)
        self.treeWidget.setObjectName(_fromUtf8("treeWidget"))

        self.treeWidget.header().setSortIndicatorShown(True)
        self.treeWidget.header().setSortIndicator(0, QtCore.Qt.AscendingOrder)

        self.treeWidget.setSortingEnabled(True)
        self.treeWidget.headerItem().setText(0, "file name")
        self.treeWidget.headerItem().setText(1, "date")
        self.treeWidget.headerItem().setText(2, "type")
        self.__sortingEnabled = self.treeWidget.isSortingEnabled()
        self.treeWidget.setSortingEnabled(False)

        verticalLayout.addWidget(self.treeWidget)

        buttonLaunchApp = QtGui.QPushButton(self)
        buttonLaunchApp.setText('OPEN')
        verticalLayout.addWidget(buttonLaunchApp)

        self.show()

class fileListGenerator():
    def __init__(self, parentWindow):
        self.parentWindow = parentWindow

    def fileLister(self):
        directoryPath = self.parentWindow.inputLineEdit.text()

        dirPath = directoryPath
        fileList = os.listdir(dirPath)
        projectFileList = []
        if len(fileList) != 0:
            for file in fileList:
                if ( file.endswith('.txt') != False ) or ( file.endswith('.py') != False ):
                    projectFileList.append(file)
        print projectFileList

        itemID = 0
        for item in projectFileList:
            filePath = dirPath + '\\' + item
            threePartSplit = item.rpartition(".")
            extension = threePartSplit[2]
            dateTimeStamp = time.ctime(os.path.getmtime(filePath))
            QDate = QtCore.QDateTime.fromString (str(dateTimeStamp), 'ddd MMM dd HH:mm:ss yyyy')
            QtGui.QTreeWidgetItem(self.parentWindow.treeWidget)
            self.parentWindow.treeWidget.topLevelItem(itemID).setText(0, item)
            self.parentWindow.treeWidget.topLevelItem(itemID).setData(1, QtCore.Qt.DisplayRole, QDate.toString('yyyy-MM-dd HH:mm:ss'))
            self.parentWindow.treeWidget.topLevelItem(itemID).setText(2, extension)
            itemID += 1

        self.parentWindow.treeWidget.setSortingEnabled(self.parentWindow._Window__sortingEnabled)

def run():
    app = QtGui.QApplication(sys.argv)
    GUI = Window()
    sys.exit(app.exec_())

run()

我尝试查找此内容并想出了使用 QAbstractItem 模型的答案?但据我了解,您只能使用带有 qTreeVIEW 的那些,而我正在使用小部件版本。我没有对项目中的数据做太多事情,所以我认为我不需要 qTreeview,所以我想将其保留为小部件。这种设置有没有办法让 UI 正确更新数据?还是我需要完全重新格式化?

提前谢谢你。

【问题讨论】:

【参考方案1】:

老实说,我不太明白你的代码。但是,如果您想将新项目添加到 QTreeWidget,您可以这样做:

item = QTreeWidgetItem()
item.setText(0, "John") # first name
item.setText(1, "Doe") # last name
item.setText(2, "35") # age

self.treeWidget.addTopLevelItem(item)

【讨论】:

您好,非常感谢您的回复。似乎这可行,但我不明白,为什么这种方法有效,而不是我的方法?当然,我所做的只是在 Designer 中制作 UI,将其转换为 Python 脚本,并尝试弄清楚它是如何放置的。只说“topLevelItem(itemID).setText()”和“addTopLevelItem(item)”有什么区别?我的意思是,在键入此内容时,我可能会明白为什么我的项目已经存在时无法工作,但即使我使用 clear() 函数,它仍然给我相同的空白结果... @user3696118 如果您要更新现有项目,topLevelItem(itemID).setText() 应该可以工作。但是要添加一个新项目,您首先需要创建一个QTreeWidgetItem,然后像我在上面所做的那样将其添加到树中。 qtreewidget.clear() 不会清除小部件中的现有数据吗?我假设如果所有内容都被删除,您可以将其视为小部件是从头开始加载的。 @user3696118 是的。但是,我不确定是什么让您感到困惑。 好吧,当我最初加载一个列表时,它会出现just fine。但是,当我继续替换列表时,它看起来像like this。数据显然在那里,但实际上并没有显示任何标签。我想 addTopLevelItem 和 topLevelItem(itemID) 几乎做同样的事情,我只是不明白为什么前者工作......【参考方案2】:

QTreeWidgets 在添加新项目时更新/重绘。所以添加一个项目,然后像这样删除它:

itemYouChanged.parent().removeChild(QTreeWidgetItem(itemYouChanged.parent()))

【讨论】:

以上是关于如何更新/刷新 qTreewidget?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 QTreeWidget 在 <list> 中的 <item>

QTreeWidget 仅在按键时拖放

pyqt5怎么刷新widget

SPOJ - QTREE(树链剖分+单点更新+区间最大值查询)

P4116 Qtree3

7.6.3 QTreeWidgetItem类函数介绍