使用PyQt5中循环提交的项刷新QTableView的内容

2024-05-14 10:40:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在开发一个用于管理虚拟环境的小GUI。在主窗口中,我希望在表视图中显示默认目录中的现有虚拟环境。到目前为止,这是有效的。在

现在我注意到,如果我选择不同的默认目录,我必须关闭GUI并再次打开它才能看到内容。不幸的是,我在计划中没有考虑到这一点(我在Python方面仍然有点缺乏经验)。在

我想添加一个按钮,您可以用它来更新表视图的内容。同时,中的现有按钮okButton设置.py(它确认所选标准目录的输入)也应该更新表视图。在

我试图使用pyqtsignal()pyqtslot(),但我不知道如何将其应用到我的代码中。例如,表中的数据来自于循环中的数据组织.py。这些项被收集到一个列表中,然后显示在表中。在

如何通过单击按钮刷新视图?我需要修改我的代码结构吗?在

以下是代码的最小可复制部分:

如果你愿意,你也可以看看repository here。没有商业背景。


main_用户界面

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *

import organize
import settings



class Ui_MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()

        self.setupUi()


    def setupUi(self):

        self.selectDefaultDir = settings.SetDefaultDirectory()

        self.setWindowTitle("MainWindow")
        self.setGeometry(430, 335, 750, 330)

        centralwidget = QWidget(self)
        self.v_Layout_1 = QVBoxLayout()
        self.v_Layout_2 = QVBoxLayout(centralwidget)

        selectButton = QPushButton(
            "Set default dir", clicked=self.selectButton_clicked
        )

        # venv table
        venvTable = QTableView(centralwidget)
        venvTable.verticalHeader().setVisible(False)
        venvTable.setSelectionBehavior(QAbstractItemView.SelectRows)
        venvTable.setEditTriggers(QAbstractItemView.NoEditTriggers)
        venvTable.setAlternatingRowColors(True)

        # adjust vertical headers
        v_HeaderTV2 = venvTable.verticalHeader()
        v_HeaderTV2.setVisible(False)
        v_HeaderTV2.setDefaultSectionSize(27.5)

        # adjust (horizontal) headers
        h_HeaderTV2 = venvTable.horizontalHeader()
        h_HeaderTV2.setDefaultAlignment(Qt.AlignLeft)
        h_HeaderTV2.setDefaultSectionSize(180)
        h_HeaderTV2.setStretchLastSection(True)

        # set table view model
        self.modelTV2 = QStandardItemModel(centralwidget)
        self.modelTV2.setColumnCount(3)
        self.modelTV2.setHorizontalHeaderLabels(
            ["Venv Name", "Version", "Path"]
        )
        venvTable.setModel(self.modelTV2)

        self.v_Layout_1.addWidget(venvTable)
        self.v_Layout_1.addWidget(selectButton)
        self.v_Layout_2.addLayout(self.v_Layout_1)
        self.setCentralWidget(centralwidget)


    def popVenvTable(self):
        """
        Populate the venv table view.
        """
        for i in range(len(organize.venvDirs)):
            self.modelTV2.insertRow(0)
            self.modelTV2.setItem(0, 0, QStandardItem(organize.venvDirs[i]))
            self.modelTV2.setItem(0, 1, QStandardItem(organize.venvVers[i]))
            self.modelTV2.setItem(0, 2, QStandardItem(organize.venvPath[i]))


    def selectButton_clicked(self):
        self.selectDefaultDir.exec_()



if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)
    ui = Ui_MainWindow()
    ui.popVenvTable()
    ui.show()

    sys.exit(app.exec_())


组织.py

^{pr2}$

设置.py

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *



class SetDefaultDirectory(QDialog):
    """
    Set the default directory, where to look for virtual environments.
    """
    def __init__(self):
        super().__init__()

        self.initUI()


    def initUI(self):
        #]===================================================================[#
        #] WINDOW SETTINGS [#================================================[#
        #]===================================================================[#

        self.setWindowTitle("Set Default Directory")
        self.setGeometry(600, 365, 500, 100)
        self.setFixedSize(500, 100)

        v_Layout = QVBoxLayout(self)
        h_Layout = QHBoxLayout()
        gridLayout = QGridLayout()

        defaultDirLabel = QLabel("Default Venv Directory:")
        self.defaultDirLineEdit = QLineEdit()
        defaultDirLabel.setBuddy(self.defaultDirLineEdit)

        folder_icon = QIcon.fromTheme("folder")

        selectDirToolButton = QToolButton(
            toolTip="Browse",
            clicked=self.selectDirTButton_clicked
        )
        selectDirToolButton.setFixedSize(26, 27)
        selectDirToolButton.setIcon(folder_icon)

        horizontalLine = QFrame()
        horizontalLine.setFrameShape(QFrame.HLine)
        horizontalLine.setFrameShadow(QFrame.Sunken)

        cancelButton = QPushButton(
            "Cancel", clicked=self.close
        )

        okButton = QPushButton(
            "OK", clicked=self.okButton_clicked
        )

        spacerItem = QSpacerItem(
            40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum
        )

        gridLayout.addWidget(defaultDirLabel, 0, 0, 1, 1)
        gridLayout.addWidget(self.defaultDirLineEdit, 0, 1, 1, 1)
        gridLayout.addWidget(selectDirToolButton, 0, 2, 1, 1)

        h_Layout.addItem(spacerItem)
        h_Layout.addWidget(okButton, 0, Qt.AlignBottom)
        h_Layout.addWidget(cancelButton, 0, Qt.AlignBottom)

        v_Layout.addLayout(gridLayout)
        v_Layout.addWidget(horizontalLine)
        v_Layout.addLayout(h_Layout)


    def selectDirTButton_clicked(self):
        """
        Select directory which should be set as default.
        """
        fileDiag = QFileDialog()

        directory = fileDiag.getExistingDirectory()
        self.defaultDirLineEdit.setText(directory)


    def okButton_clicked(self):
        """
        Store the absolute path (as str) to the selected dir in 'def/default'.
        """
        with open("def/default", 'w') as default:
            default.write(self.defaultDirLineEdit.text())
            default.close()

        self.close()





if __name__ == "__main__":
    import sys

    app = QApplication(sys.argv)

    settingsUI = SetDefaultDirectory()
    settingsUI.show()

    sys.exit(app.exec_())


Tags: fromimportselfdefaultdefsyspyqt5layout
1条回答
网友
1楼 · 发布于 2024-05-14 10:40:47

您的代码存在以下错误或问题:

  • venvs查找的函数不应该填充列表,而是返回一个列表,因此您可以在需要时调用它

  • 返回vens的方法有错误,例如它没有验证“bin”是否存在,也没有构建与“/”连接的路由,而是使用os.path.join操作系统().

  • 不要使用相对路径,而是构建绝对路径。

  • 创建一个存储venvs信息的数据结构

考虑到上述情况,解决方案是:

main_用户界面

# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtGui, QtWidgets

import organize
import settings


class Ui_MainWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi()

    def setupUi(self):

        self.selectDefaultDir = settings.SetDefaultDirectory()

        self.setWindowTitle("MainWindow")
        self.setGeometry(430, 335, 750, 330)

        centralwidget = QtWidgets.QWidget(self)
        self.v_Layout_1 = QtWidgets.QVBoxLayout()
        self.v_Layout_2 = QtWidgets.QVBoxLayout(centralwidget)

        selectButton = QtWidgets.QPushButton(
            "Set default dir", clicked=self.selectButton_clicked
        )

        # venv table
        venvTable = QtWidgets.QTableView(
            centralwidget,
            selectionBehavior=QtWidgets.QAbstractItemView.SelectRows,
            editTriggers=QtWidgets.QAbstractItemView.NoEditTriggers,
            alternatingRowColors=True,
        )

        # adjust vertical headers
        v_HeaderTV2 = venvTable.verticalHeader()
        v_HeaderTV2.hide()
        v_HeaderTV2.setDefaultSectionSize(27.5)

        # adjust (horizontal) headers
        h_HeaderTV2 = venvTable.horizontalHeader()
        h_HeaderTV2.setDefaultAlignment(QtCore.Qt.AlignLeft)
        h_HeaderTV2.setDefaultSectionSize(180)
        h_HeaderTV2.setStretchLastSection(True)

        # set table view model
        self.modelTV2 = QtGui.QStandardItemModel(0, 3, centralwidget)
        self.modelTV2.setHorizontalHeaderLabels(["Venv Name", "Version", "Path"])
        venvTable.setModel(self.modelTV2)

        self.v_Layout_1.addWidget(venvTable)
        self.v_Layout_1.addWidget(selectButton)
        self.v_Layout_2.addLayout(self.v_Layout_1)
        self.setCentralWidget(centralwidget)

    def popVenvTable(self):
        """
        Populate the venv table view.
        """
        self.modelTV2.setRowCount(0)
        for info in organize.get_venvs_default():
            self.modelTV2.insertRow(0)
            for i, text in enumerate((info.name, info.version, info.directory)):
                self.modelTV2.setItem(0, i, QtGui.QStandardItem(text))
            print(info)

    def selectButton_clicked(self):
        if self.selectDefaultDir.exec_() == QtWidgets.QDialog.Accepted:
            self.popVenvTable()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    ui = Ui_MainWindow()
    ui.popVenvTable()
    ui.show()

    sys.exit(app.exec_())

组织.py

^{pr2}$

设置.py

# -*- coding: utf-8 -*-
import os

from PyQt5 import QtCore, QtGui, QtWidgets


class SetDefaultDirectory(QtWidgets.QDialog):
    """
    Set the default directory, where to look for virtual environments.
    """

    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        # ]===================================================================[#
        # ] WINDOW SETTINGS [#================================================[#
        # ]===================================================================[#

        self.setWindowTitle("Set Default Directory")
        self.move(600, 365)
        self.setFixedSize(500, 100)

        v_Layout = QtWidgets.QVBoxLayout(self)
        h_Layout = QtWidgets.QHBoxLayout()
        gridLayout = QtWidgets.QGridLayout()

        defaultDirLabel = QtWidgets.QLabel("Default Venv Directory:")
        self.defaultDirLineEdit = QtWidgets.QLineEdit()
        defaultDirLabel.setBuddy(self.defaultDirLineEdit)

        folder_icon = QtGui.QIcon.fromTheme("folder")

        selectDirToolButton = QtWidgets.QToolButton(
            toolTip="Browse", clicked=self.selectDirTButton_clicked, icon=folder_icon
        )
        selectDirToolButton.setFixedSize(26, 27)

        horizontalLine = QtWidgets.QFrame(
            frameShape=QtWidgets.QFrame.HLine, frameShadow=QtWidgets.QFrame.Sunken
        )

        cancelButton = QtWidgets.QPushButton("Cancel", clicked=self.reject)

        okButton = QtWidgets.QPushButton("OK", clicked=self.okButton_clicked)

        gridLayout.addWidget(defaultDirLabel, 0, 0, 1, 1)
        gridLayout.addWidget(self.defaultDirLineEdit, 0, 1, 1, 1)
        gridLayout.addWidget(selectDirToolButton, 0, 2, 1, 1)

        h_Layout.addStretch()
        h_Layout.addWidget(okButton, 0, QtCore.Qt.AlignBottom)
        h_Layout.addWidget(cancelButton, 0, QtCore.Qt.AlignBottom)

        v_Layout.addLayout(gridLayout)
        v_Layout.addWidget(horizontalLine)
        v_Layout.addLayout(h_Layout)

    def selectDirTButton_clicked(self):
        """
        Select directory which should be set as default.
        """
        directory = QtWidgets.QFileDialog.getExistingDirectory()
        self.defaultDirLineEdit.setText(directory)

    def okButton_clicked(self):
        """
        Store the absolute path (as str) to the selected dir in 'def/default'.
        """
        current_dir = os.path.dirname(os.path.realpath(__file__))
        default_file = os.path.join(current_dir, "def", "default")
        with open(default_file, "w") as default:
            default.write(self.defaultDirLineEdit.text())
        self.accept()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    settingsUI = SetDefaultDirectory()
    settingsUI.show()

    sys.exit(app.exec_())

相关问题 更多 >

    热门问题