从组合框中进行选择时出现意外的行乘法



在列表中选择一行后,出现了意外行为。我从表单上方的下拉列表中加载文件夹的路径,然后获取所选文件夹中的内容(只有目录,没有文件(,然后用鼠标从列表中的文件夹中选择文件,并获取其到控制台的完整路径。这是必要的,以便在未来以不同的形式使用它。但是,如果我通过从列表中选择它并从新文件夹中选择一个目录来切换到另一个文件夹,我将获得控制台的路径2次。如果我再次选择下拉列表中的任何文件夹,即使是之前选择的文件夹,在选择该文件夹中的任何项目后,我将获得它的路径3次,以此类推。从下拉列表中每次下载主文件夹都会产生一个"+1〃;到列表中所选文件夹的路径

我不明白为什么会发生这种情况,以及如何应对?

# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file '3.ui'
#
# Created by: PyQt5 UI code generator 5.15.1
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.

from PyQt5 import QtCore, QtGui, QtWidgets
import sys
import os
from PyQt5.Qt import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *


mydir = 'C:/Users/Philipp_WORK/Desktop/Python/db/'
dirname = os.listdir(mydir)
print("this is the first list: " + str(dirname)) # for debug


def get_dirpaths(directory):
dir_paths = [] 
for root, directories, files in os.walk(directory):
for dirs in directories:
directory = os.path.join(root, dirs)
dir_paths.append(directory)  
return dir_paths 
global full_dirs_paths
full_dirs_paths = get_dirpaths(mydir)



# combine one DICT from two lists
global mydictfordbchoser

mydictfordbchoser = dict(zip(dirname, full_dirs_paths))
print("this is the COMBINED DICT: " + str(mydictfordbchoser)) # for debug



class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(350, 300)
MainWindow.setMinimumSize(QtCore.QSize(350, 300))
MainWindow.setMaximumSize(QtCore.QSize(350, 800))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_2 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_2.setObjectName("gridLayout_2")
self.groupSelectFolder = QtWidgets.QGroupBox(self.centralwidget)
self.groupSelectFolder.setAlignment(QtCore.Qt.AlignCenter)
self.groupSelectFolder.setObjectName("groupSelectFolder")
self.gridLayout = QtWidgets.QGridLayout(self.groupSelectFolder)
self.gridLayout.setObjectName("gridLayout")
self.dbChooser = QtWidgets.QComboBox(self.groupSelectFolder)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.dbChooser.sizePolicy().hasHeightForWidth())
self.dbChooser.setSizePolicy(sizePolicy)
self.dbChooser.setSizeAdjustPolicy(QtWidgets.QComboBox.AdjustToContentsOnFirstShow)
self.dbChooser.setObjectName("dbChooser")
self.gridLayout.addWidget(self.dbChooser, 0, 0, 1, 1)
self.listOfPosts = QtWidgets.QListView(self.groupSelectFolder)
self.listOfPosts.setObjectName("listOfPosts")
self.gridLayout.addWidget(self.listOfPosts, 1, 0, 1, 1)
self.gridLayout_2.addWidget(self.groupSelectFolder, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
self.dbChooser.setCurrentIndex(-1)
QtCore.QMetaObject.connectSlotsByName(MainWindow)

self.put_all_folder_in_combobox() # connection to function below

self.dbChooser.currentIndexChanged[str].connect(self.show_posts_in_posts_window) # connection to function below



def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "test"))
self.groupSelectFolder.setTitle(_translate("MainWindow", "Posts_will_Be_Here"))
self.dbChooser.setCurrentText(_translate("MainWindow", "select_post"))
self.dbChooser.setPlaceholderText(_translate("MainWindow", "select_post"))
# my code starts here


def put_all_folder_in_combobox(self):
self.dbChooser.addItems(mydictfordbchoser) # mydictfordbchoser - global var

def show_posts_in_posts_window(self, link_to_view):
path = ''
path = str(mydictfordbchoser[link_to_view])
self.model = QtWidgets.QFileSystemModel()
self.model.setRootPath(QtCore.QDir.rootPath())
self.listOfPosts.setModel(self.model)
self.listOfPosts.setRootIndex(self.model.index(path))

self.listOfPosts.clicked.connect(self.get_path_from_listOfPosts)

print(path) # for debug

def get_path_from_listOfPosts(self):
index = self.listOfPosts.currentIndex()
filepath = self.model.filePath(index)
print(str(filepath) + "/") # why here i get multiplication rows as time as i switch groupbox ?



if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())

一些图片以更好地理解(因为我的英语不完美(

程序启动

加载主文件夹并点击1到10文件夹一次

将目录更改为空

再次返回第一个目录

点击一次从一个到四个文件夹,得到这个奇怪的行为(每个文件夹打印到控制台x3次(

虽然Qt信号连接的行为几乎是回调,但它们并不是唯一的:您可以多次连接更多的插槽/函数,包括相同的函数。

考虑以下内容:

self.someButton.clicked.connect(self.someFunction)
self.someButton.clicked.connect(self.someFunction)
def someFunction(self):
print('clicked')

结果将是;点击";将在每次单击按钮时打印两次

代码的问题是,每次更改dbChooser索引时,都要连接self.listOfPostsclicked信号。

一般建议是在类的__init__中建立所有连接,或者只有当您确定建立连接的函数在发送器(信号发射器(或接收器(被调用的函数(的使用寿命内只运行一次时。

由于在您的情况下,只有在选择了有效索引时才会调用get_path_from_listOfPosts,因此如果模型仍然为空,则没有出现任何异常的风险,因此只需在setupUi:中移动连接即可

class Ui_MainWindow(object):
def setupUi(self, MainWindow):
# ...
self.listOfPosts.clicked.connect(self.get_path_from_listOfPosts)

也就是说,一些重要的建议:

  1. clicked已经将点击的索引作为其参数,不需要使用index = self.listOfPosts.currentIndex()
def get_path_from_listOfPosts(self, index):
filepath = self.model.filePath(index)
  1. 不需要每次都创建新的模型:在setupUi中设置模型,需要时只需调用setRootPath();除了创建同一模型的新实例毫无意义之外,QFileSystemModel是一个非常复杂的模型,需要更多的资源(它还提供了一种缓存机制,如果重新创建就会变得毫无用处(:您应该尽可能重用同一个实例
  2. 除非您真的知道全局变量应该用于什么以及它们的行为,否则应该始终避免全局变量;一般规则是,如果你使用它们,那是因为你的对象结构有问题
  3. 正如文件头中明确指出的那样,除非真的知道自己在做什么,否则不应该编辑pyuic生成的文件:修改这些文件通常被认为是不好的做法;阅读有关使用Designer的指南中如何正确使用这些文件

最新更新