yxxxzx123 发表于 2024-3-16 07:41:33

Pyside6 for 语句卡顿求助~~

现有PySide6代码如下:
class BaseWindow(QWidget):

        ......

class WindowA(BaseWindow):

      .....

   class WindowB(BaseWindow):

      .....

          def __init__(self):
              super().__init__()
                        # 设置窗体大小和背景颜色
              self.setFixedSize(1440, 900)

                self.pushButton_3 = QtWidgets.QPushButton(parent=self.verticalLayoutWidget)
      

        def retranslateUi(self):
                _translate = QtCore.QCoreApplication.translate
               
                self.pushButton_3.clicked.connect(self.exclude_rows_and_cols)

       ### 排除行(列)录入储存
    def exclude_rows_and_cols(self, exclude_rows_and_cols):
      
      for sheet_name in Exclud_Book.sheet_names():
            
            exclude_rows_input = input()
            
            
            exclude_cols_input = input()
            

            exclude_rules = {'行': exclude_rows, '列': exclude_cols}
            
      return exclude_rules
               

只要一执行红色的for sheet_name in Exclud_Book.sheet_names():就卡死,我把它放在哪一个按钮方法中也是一样卡顿。。。。

屏敝掉这一句就不卡顿。。。。

恳请各位大神指点一下,应该怎么处理?不胜感激~~

FishC 发表于 2024-3-16 07:41:44

在您提供的代码中,并没有看到`Exclud_Book`的定义,所以无法确定该变量的来源或内容。但是,在您执行 `for sheet_name in Exclud_Book.sheet_names():` 时出现卡顿是可以理解的,因为这个循环似乎在处理较大的数据集。

如果 `Exclud_Book` 是一个 Excel 文件,并且您使用的是 `pandas` 库来读取和操作数据,则可以考虑以下几点:

1. 检查您的代码是否正确引入了 `pandas` 库。
2. 确保您在使用 `pandas` 之前正确地安装了它。可以通过运行 `pip install pandas` 来安装 `pandas`。
3. 如果您的 Excel 文件非常大,可能需要耐心等待循环完成。您可以尝试先使用较小规模的数据进行测试,以确认卡顿问题是否与数据量有关。
4. 考虑优化您的代码逻辑,以降低计算复杂度。例如,避免在循环内部执行耗时的操作,或者使用更高效的算法来处理数据。

另外,请注意命名规范,按照惯例,类名应该首字母大写,函数名应该小写,使用下划线分隔单词。这将使您的代码更易于阅读和理解。

如果您能提供更多关于 `Exclud_Book` 的信息,包括其定义和所使用的库,我将能够提供更具体的帮助。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

yxxxzx123 发表于 2024-3-16 07:45:41

FishC 发表于 2024-3-16 07:41
在您提供的代码中,并没有看到`Exclud_Book`的定义,所以无法确定该变量的来源或内容。但是,在您执行 `for ...

Exclud_Book = xlrd.open_workbook(file_path)

xls文件也不大,数据量特别小。。。。

FishC 发表于 2024-3-16 07:45:53

yxxxzx123 发表于 2024-03-16 07:45
Exclud_Book = xlrd.open_workbook(file_path)

xls ...

如果`Exclud_Book`是使用`xlrd`库打开的Excel文件,并且您表示数据量非常小,那么导致卡顿的原因可能在于其他地方。这里给出一些可能的解决方案:

1. 检查`xlrd`库的版本是否是最新的,可以通过运行`pip install xlrd --upgrade`来更新库。
2. 确保您的环境中没有其他耗费大量资源的进程运行。关闭其他不必要的程序或进程,确保系统资源充足。
3. 查看代码其他部分是否存在潜在的性能问题。可能是循环内部的其他操作导致卡顿,例如数据处理、计算等。您可以尝试注释掉除了读取Excel文件的部分,然后逐步取消注释,找到导致性能下降的具体代码。
4. 如果可能的话,尝试将Excel文件转换为其他格式,例如CSV文件,然后使用`pandas`库进行读取和处理。有时候其他格式的文件读取速度更快。

如果上述解决方案都没有解决问题,那么可能需要更多的上下文信息,包括完整的代码和涉及到的数据文件,才能帮助您进一步分析和解决问题。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

yxxxzx123 发表于 2024-3-16 07:49:57

FishC 发表于 2024-3-16 07:45
如果`Exclud_Book`是使用`xlrd`库打开的Excel文件,并且您表示数据量非常小,那么导致卡顿的原因可能在 ...

如果我要把这一段代码加入线程语句,应该怎么写呢?

FishC 发表于 2024-3-16 07:50:05

yxxxzx123 发表于 2024-03-16 07:49
如果我要把这一段代码加入线程语句,应该怎么写呢?

如果您想将代码放在一个线程中执行,可以使用Python的`threading`模块来创建和管理线程。下面是一个示例代码,展示如何将您的代码放在一个线程内执行:

import threading
import xlrd

class MyThread(threading.Thread):
    def __init__(self):
      super().__init__()

    def run(self):
      # 在这里放入您的代码
      Exclud_Book = xlrd.open_workbook(file_path)
      for sheet_name in Exclud_Book.sheet_names():
            exclude_rows_input = input()
            exclude_cols_input = input()
            exclude_rules = {'行': exclude_rows_input, '列': exclude_cols_input}
            # 在这里对数据进行处理或执行其他操作
            print(exclude_rules)

# 创建线程并启动
thread = MyThread()
thread.start()

在这个示例中,我们创建了一个名为`MyThread`的自定义线程类,继承自`threading.Thread`类。在`run`方法中,我们将您的代码放入其中。然后,通过创建`MyThread`的实例,调用`start`方法来启动线程。

请注意,在线程中执行GUI操作可能会导致问题,因为GUI通常是单线程应用程序。如果您在PySide6中使用这些代码并遇到线程相关的问题,您可能需要使用PySide6提供的特定功能来在主线程和工作者线程之间进行通信,例如信号和槽机制。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

yxxxzx123 发表于 2024-3-16 07:53:10

FishC 发表于 2024-3-16 07:50
如果您想将代码放在一个线程中执行,可以使用Python的`threading`模块来创建和管理线程。下面是一个示 ...

烦请在1#楼的代码基础上加入线程写法。

FishC 发表于 2024-3-16 07:53:17

yxxxzx123 发表于 2024-03-16 07:53
烦请在1#楼的代码基础上加入线程写法。

在1#楼的代码基础上,加入线程的写法如下所示:

import threading
from PySide6.QtCore import Qt
from PySide6.QtWidgets import QApplication, QWidget, QVBoxLayout, QPushButton

class BaseWindow(QWidget):
    def __init__(self):
      super().__init__()

class WindowA(BaseWindow):
    def __init__(self):
      super().__init__()

class WindowB(BaseWindow):
    def __init__(self):
      super().__init__()

class MyThread(threading.Thread):
    def run(self):
      # 在这里放入您的代码
      for sheet_name in Exclud_Book.sheet_names():
            exclude_rows_input = input()
            exclude_cols_input = input()
            exclude_rules = {'行': exclude_rows_input, '列': exclude_cols_input}
            # 在这里对数据进行处理或执行其他操作
            print(exclude_rules)

if __name__ == "__main__":
    app = QApplication([])
   
    # 创建窗口
    window = WindowB()
    window.setFixedSize(1440, 900)
    layout = QVBoxLayout(window)
   
    # 创建按钮
    button = QPushButton("点击")
    layout.addWidget(button)

    def start_thread():
      thread = MyThread()
      thread.start()

    # 绑定按钮点击事件
    button.clicked.connect(start_thread)

    window.show()
    app.exec()

在这个示例中,我创建了一个`MyThread`类,并让它继承自`threading.Thread`。在`run`方法中,您可以将您的代码放入其中。

然后,我在主程序中创建了一个窗口和一个按钮。当按钮被点击时,会调用`start_thread`函数来创建并启动线程。

请注意,在PySide6中,界面操作应该在主线程中进行,所以我们只在子线程中执行您的代码逻辑部分。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

凊风 发表于 2024-3-16 13:13:11

本帖最后由 凊风 于 2024-3-16 13:14 编辑

FishC 发表于 2024-3-16 07:53
在1#楼的代码基础上,加入线程的写法如下所示:




我写成下面这样:

class MyThread(threading.Thread):
    def run(self):
      if self.File_Type == 'xls':
            file_name = "汇总表.xls"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = xlrd.open_workbook(file_path)
      else:
            file_name = "汇总表.xlsx"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = load_workbook(file_path)

然后报错:
         Exception in thread Thread-1:
Traceback (most recent call last):
File "D:\Tools\Python\Lib\threading.py", line 1045, in _bootstrap_inner
    self.run()
File "D:\Python\pythonProject\20240316\xtt031601.py", line 1064, in run
    if self.File_Type == 'xls':
       ^^^^^^^^^^^^^^
AttributeError: 'MyThread' object has no attribute 'File_Type'


self.File_Type == 'xls': 是上一个按钮事件存入的数据。

FishC 发表于 2024-3-16 13:15:28

凊风 发表于 2024-03-16 13:13
我写成下面这样:

class MyThread(threading.Threa ...

在您的代码中,报错是因为`MyThread`对象没有`File_Type`属性。要解决此问题,您需要将`File_Type`作为`MyThread`类的初始化参数,并在创建线程对象时传递该参数。修改代码如下:

class MyThread(threading.Thread):
    def __init__(self, file_type):
      super().__init__()
      self.File_Type = file_type

    def run(self):
      if self.File_Type == 'xls':
            file_name = "汇总表.xls"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = xlrd.open_workbook(file_path)
      else:
            file_name = "汇总表.xlsx"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = load_workbook(file_path)

# 创建线程对象时传入File_Type参数
thread = MyThread('xls')

在创建`MyThread`对象时,将文件类型('xls'或其他值)作为参数传递给`MyThread`类的初始化方法。然后,您可以在`run`方法中使用`self.File_Type`来访问该参数。

请确保在调用`start`方法启动线程之前,先为`MyThread`对象设置`File_Path`属性,这样您的代码中的文件路径拼接部分才能正常工作。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

凊风 发表于 2024-3-16 13:26:19

FishC 发表于 2024-3-16 13:15
在您的代码中,报错是因为`MyThread`对象没有`File_Type`属性。要解决此问题,您需要将`File_Type`作为 ...

我现在写成这样:
self.pushButton_3.clicked.connect(self.start_thread)

    def start_thread(self):
      thread = MyThread()
      thread.start()

class MyThread(threading.Thread):
    def __init__(self, file_type):
      super().__init__()
      self.File_Type = file_type

    def run(self):
      if self.File_Type == 'xls':
            file_name = "汇总表.xls"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = xlrd.open_workbook(file_path)
      else:
            file_name = "汇总表.xlsx"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = load_workbook(file_path)
      
      for sheet_name in Exclud_Book.sheet_names():         
               
            exclude_rows_input = input()
            if exclude_rows_input:
                self.exclude_rows =
         
            exclude_cols_input = input()
            if exclude_cols_input:
                exclude_cols =

            exclude_rules = {'排除行': exclude_rows, '排除列': exclude_cols}         
                                             
      print(exclude_rules)


# 创建线程对象时传入File_Type参数
thread = MyThread('xls')



但是运行时报错:

Traceback (most recent call last):
File "D:\Python\pythonProject\20240316\xtt031601.py", line 1057, in start_thread
    thread = MyThread()
             ^^^^^^^^^^
TypeError: MyThread.__init__() missing 1 required positional argument: 'file_type'

FishC 发表于 2024-3-16 13:26:42

凊风 发表于 2024-03-16 13:26
我现在写成这样:
self.pushButton_3.clicked.connec ...

在您的代码中,报错是因为`MyThread`类的初始化方法需要传递一个`file_type`参数,但是在创建`MyThread`对象时没有传递该参数。要解决此问题,您可以修改`start_thread`方法和`MyThread`类的定义如下:self.pushButton_3.clicked.connect(lambda: self.start_thread('xls'))def start_thread(self, file_type):    thread = MyThread(file_type)    thread.start()class MyThread(threading.Thread):    def __init__(self, file_type):      super().__init__()      self.File_Type = file_type    def run(self):      if self.File_Type == 'xls':            file_name = "汇总表.xls"            # 拼接文件路径            file_path = os.path.join(self.File_Path, file_name)            Exclud_Book = xlrd.open_workbook(file_path)      else:            file_name = "汇总表.xlsx"            # 拼接文件路径            file_path = os.path.join(self.File_Path, file_name)            Exclud_Book = load_workbook(file_path)            for sheet_name in Exclud_Book.sheet_names():                exclude_rows_input = input()                if exclude_rows_input:                  self.exclude_rows = exclude_cols_input = input()                if exclude_cols_input:                  exclude_cols = exclude_rules = {'排除行': exclude_rows, '排除列': exclude_cols}                print(exclude_rules)在连接按钮信号时,使用`lambda`函数传递文件类型参数('xls')给`start_thread`方法。然后,在`start_thread`方法中将该参数传递给`MyThread`的初始化方法以创建线程对象。这样,线程对象就会正确获得文件类型参数,并在运行时不再报错。请注意,在运行线程时,您需要适当设置`self.File_Path`属性,这样代码中的文件路径拼接才能正常工作。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

凊风 发表于 2024-3-16 13:29:01

FishC 发表于 2024-3-16 13:26
在您的代码中,报错是因为`MyThread`类的初始化方法需要传递一个`file_type`参数,但是在创建`MyThread ...

回复请注意python格式

FishC 发表于 2024-3-16 13:29:14

凊风 发表于 2024-03-16 13:29
回复请注意python格式

抱歉,对于代码格式的部分没有进行恰当的处理。以下是修正后的代码,并注意了Python的正确缩进和空格使用:

self.pushButton_3.clicked.connect(lambda: self.start_thread('xls'))

def start_thread(self, file_type):
    thread = MyThread(file_type)
    thread.start()

class MyThread(threading.Thread):
    def __init__(self, file_type):
      super().__init__()
      self.File_Type = file_type

    def run(self):
      if self.File_Type == 'xls':
            file_name = "汇总表.xls"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = xlrd.open_workbook(file_path)
      else:
            file_name = "汇总表.xlsx"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = load_workbook(file_path)

      for sheet_name in Exclud_Book.sheet_names():
            exclude_rows_input = input()
            if exclude_rows_input:
                self.exclude_rows = exclude_cols_input = input()
            if exclude_cols_input:
                exclude_cols = exclude_rules = {'排除行': exclude_rows, '排除列': exclude_cols}

      print(exclude_rules)

请注意在代码中增加了适当的缩进,确保代码块的层次结构正确,并使用了4个空格作为缩进。这是Python中常用的代码风格。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

凊风 发表于 2024-3-16 13:32:09

FishC 发表于 2024-3-16 13:29
抱歉,对于代码格式的部分没有进行恰当的处理。以下是修正后的代码,并注意了Python的正确缩进和空格使 ...

报错:

Exception in thread Thread-1:
Traceback (most recent call last):
File "D:\Tools\Python\Lib\threading.py", line 1045, in _bootstrap_inner
    self.run()
File "D:\Python\pythonProject\20240316\xtt031601.py", line 1071, in run
    file_path = os.path.join(self.File_Path, file_name)
                           ^^^^^^^^^^^^^^
AttributeError: 'MyThread' object has no attribute 'File_Path'


回复请注意python格式

FishC 发表于 2024-3-16 13:32:31

凊风 发表于 2024-03-16 13:32
报错:

Exception in thread Thread-1:
Traceback ...

非常抱歉,我之前的回答中有一处错误。在 `MyThread` 类的 `run` 方法中,`self.File_Path` 是一个未定义的变量,因此会引发 `AttributeError` 异常。

如果您想在 `MyThread` 类中使用 `File_Path` 变量,请将其作为参数传递给 `MyThread` 类的构造函数,并存储为实例属性。下面是修正后的代码:

self.pushButton_3.clicked.connect(lambda: self.start_thread('xls'))

def start_thread(self, file_type):
    thread = MyThread(file_type, self.File_Path)# 将 File_Path 作为参数传递给 MyThread
    thread.start()

class MyThread(threading.Thread):
    def __init__(self, file_type, file_path):# 接收 File_Path 参数并存储为实例属性
      super().__init__()
      self.File_Type = file_type
      self.File_Path = file_path
   
    def run(self):
      if self.File_Type == 'xls':
            file_name = "汇总表.xls"
      else:
            file_name = "汇总表.xlsx"
      
      # 拼接文件路径
      file_path = os.path.join(self.File_Path, file_name)
      
      if self.File_Type == 'xls':
            Exclud_Book = xlrd.open_workbook(file_path)
      else:
            Exclud_Book = load_workbook(file_path)
      
      for sheet_name in Exclud_Book.sheet_names():
            exclude_rows_input = input()
            if exclude_rows_input:
                self.exclude_rows = exclude_cols_input = input()
            if exclude_cols_input:
                exclude_cols = exclude_rules = {'排除行': exclude_rows, '排除列': exclude_cols}
      
      print(exclude_rules)

现在,`MyThread` 类的构造函数接收 `file_path` 参数,并将其存储为实例属性 `self.File_Path`。这样,在 `run` 方法中就可以正常使用 `self.File_Path` 而不会引发异常了。请确保您在调用 `start_thread` 方法时正确设置 `self.File_Path` 的值。

希望这次能够解决问题,如果还有其他疑问,请随时提出。再次对之前的错误回答表示歉意。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

凊风 发表于 2024-3-16 13:43:15

FishC 发表于 2024-3-16 13:32
非常抱歉,我之前的回答中有一处错误。在 `MyThread` 类的 `run` 方法中,`self.File_Path` 是一个未定 ...

那请问另一个按钮也可以参照这样写吗?

如果可以,那岂不是很多class MyThread(threading.Thread):?

FishC 发表于 2024-3-16 13:43:40

凊风 发表于 2024-03-16 13:43
那请问另一个按钮也可以参照这样写吗?

如果可以 ...

是的,您可以为每个按钮创建一个单独的线程类,但在这种情况下,会有很多相似的线程类。为了避免重复编写相似的代码,您可以将线程类的功能封装在一个通用的线程类中,并在每个按钮的点击事件中实例化该线程类。下面是一个示例:class MyThread(threading.Thread):    def __init__(self, file_type, file_path):      super().__init__()      self.File_Type = file_type      self.File_Path = file_path      def run(self):      if self.File_Type == 'xls':            file_name = "汇总表.xls"      else:            file_name = "汇总表.xlsx"                # 拼接文件路径      file_path = os.path.join(self.File_Path, file_name)                if self.File_Type == 'xls':            Exclud_Book = xlrd.open_workbook(file_path)      else:            Exclud_Book = load_workbook(file_path)                for sheet_name in Exclud_Book.sheet_names():            exclude_rows_input = input()            if exclude_rows_input:                self.exclude_rows = exclude_cols_input = input()            if exclude_cols_input:                exclude_cols = exclude_rules = {'排除行': exclude_rows, '排除列': exclude_cols}                print(exclude_rules)class BaseWindow(QWidget):    def __init__(self):      super().__init__()      # 其他初始化操作    def start_thread(self, file_type):      thread = MyThread(file_type, self.File_Path)# 将 File_Path 作为参数传递给 MyThread      thread.start()class WindowA(BaseWindow):    def __init__(self):      super().__init__()      # 其他初始化操作      self.pushButton_1.clicked.connect(lambda: self.start_thread('xls'))# 按钮1的点击事件      self.pushButton_2.clicked.connect(lambda: self.start_thread('xlsx'))# 按钮2的点击事件class WindowB(BaseWindow):    def __init__(self):      super().__init__()      # 其他初始化操作      self.pushButton_3.clicked.connect(lambda: self.start_thread('xls'))# 按钮3的点击事件      self.pushButton_4.clicked.connect(lambda: self.start_thread('xlsx'))# 按钮4的点击事件通过将常用的线程功能封装在 `MyThread` 类中,您可以在每个窗口类中实例化该线程类,并且只需为每个按钮的点击事件连接对应的线程启动函数即可。这样,您只需要编写一次线程类的代码,并在多个窗口中重复使用,避免了大量的重复代码。希望这个解决方案对您有所帮助。如有其他问题,请随时追问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。

凊风 发表于 2024-3-16 13:44:14

FishC 发表于 2024-3-16 13:43
是的,您可以为每个按钮创建一个单独的线程类,但在这种情况下,会有很多相似的线程类。为了避免重复编 ...

回复请注意python格式

FishC 发表于 2024-3-16 13:44:32

凊风 发表于 2024-03-16 13:44
回复请注意python格式

非常抱歉,下面是更符合Python格式的代码示例:

import threading
import os
import xlrd
from openpyxl import load_workbook

class MyThread(threading.Thread):
    def __init__(self, file_type, file_path):
      super().__init__()
      self.File_Type = file_type
      self.File_Path = file_path
      
    def run(self):
      if self.File_Type == 'xls':
            file_name = "汇总表.xls"
      else:
            file_name = "汇总表.xlsx"
            
      # 拼接文件路径
      file_path = os.path.join(self.File_Path, file_name)
      
      if self.File_Type == 'xls':
            Exclud_Book = xlrd.open_workbook(file_path)
      else:
            Exclud_Book = load_workbook(file_path)
            
      for sheet_name in Exclud_Book.sheet_names():
            exclude_rows_input = input()
            
            if exclude_rows_input:
                self.exclude_rows = exclude_cols_input = input()
               
            if exclude_cols_input:
                exclude_cols = exclude_rules = {'排除行': exclude_rows, '排除列': exclude_cols}
                print(exclude_rules)

class BaseWindow(QWidget):
    def __init__(self):
      super().__init__()
      # 其他初始化操作
   
    def start_thread(self, file_type):
      thread = MyThread(file_type, self.File_Path)# 将 File_Path 作为参数传递给 MyThread
      thread.start()

class WindowA(BaseWindow):
    def __init__(self):
      super().__init__()
      # 其他初始化操作
      self.pushButton_1.clicked.connect(lambda: self.start_thread('xls'))# 按钮1的点击事件
      self.pushButton_2.clicked.connect(lambda: self.start_thread('xlsx'))# 按钮2的点击事件

class WindowB(BaseWindow):
    def __init__(self):
      super().__init__()
      # 其他初始化操作
      self.pushButton_3.clicked.connect(lambda: self.start_thread('xls'))# 按钮3的点击事件
      self.pushButton_4.clicked.connect(lambda: self.start_thread('xlsx'))# 按钮4的点击事件

希望这次的回复符合您的格式要求,如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
页: [1] 2
查看完整版本: Pyside6 for 语句卡顿求助~~