鱼C论坛

 找回密码
 立即注册
123
返回列表 发新帖
楼主: yxxxzx123

多线程求教~~

[复制链接]
发表于 2024-3-15 09:15:00 | 显示全部楼层
FishC 发表于 2024-3-14 22:20
如果在窗体B中的按钮调用了窗体A中的方法来处理耗时任务,那么将线程类定义在窗体A中是可行的。您可以 ...

"如果在窗体B中的按钮调用了窗体A中的方法来处理耗时任务,那么将线程类定义在窗体A中是可行的。" 实际上,我并没有如你所讲的B窗体来调用A窗体的方法,因为打开B窗体时,A窗体已经关闭了。。。
并且 ,所有按钮都是在B窗体中。。。按钮方法也是全部置于B窗体中。。。

下面这个fro语句卡顿的很厉害,麻烦想想办法。

for sheet_name in Exclud_Book.sheet_names():

回复请注意Python格式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-15 09:17:07 | 显示全部楼层
FishC 发表于 2024-3-14 22:20
如果在窗体B中的按钮调用了窗体A中的方法来处理耗时任务,那么将线程类定义在窗体A中是可行的。您可以 ...

"如果在窗体B中的按钮调用了窗体A中的方法来处理耗时任务,那么将线程类定义在窗体A中是可行的。" 实际上,我并没有如你所讲的B窗体来调用A窗体的方法,因为打开B窗体时,A窗体已经关闭了。。。
并且 ,所有按钮都是在B窗体中。。。按钮方法也是全部置于B窗体中。。。

下面这个fro语句卡顿的很厉害,麻烦想想办法。

for sheet_name in Exclud_Book.sheet_names():

回复请注意Python格式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-15 09:17:40 | 显示全部楼层
我忘记了AI是不理我的。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-15 09:17:40 | 显示全部楼层
yxxxzx123 发表于 2024-03-15 09:17
"如果在窗体B中的按钮调用了窗体A中的方法来处理耗时 ...


如果你的窗口A已经关闭,并且所有的按钮和相关方法都在窗口B中,那么你可以将线程类定义在窗口B中,以便在按钮方法中启动线程来处理耗时任务。下面是一个可能的解决方案,使用`QRunnable`和`QThreadPool`来实现多线程执行任务的方式。

  1. from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLabel
  2. from PySide6.QtCore import QRunnable, QObject, Signal, Qt, QThreadPool

  3. class MyRunnable(QRunnable):
  4.     def __init__(self):
  5.         super().__init__()
  6.         self.setAutoDelete(True)

  7.     def run(self):
  8.         # 在这里编写耗时的任务代码
  9.         # ...
  10.         # 任务完成后发射信号
  11.         exclude_rules = {'1': exclude_rows, '2': exclude_cols}
  12.         self.finished.emit(exclude_rules)

  13.     finished = Signal(dict)

  14. class WindowB(QMainWindow):
  15.     def __init__(self):
  16.         super().__init__()
  17.         self.threadpool = QThreadPool()
  18.         
  19.         self.label = QLabel("进度条")
  20.         self.button = QPushButton("启动线程")
  21.         self.button.clicked.connect(self.start_thread)

  22.         layout = QVBoxLayout()
  23.         layout.addWidget(self.label)
  24.         layout.addWidget(self.button)

  25.         central_widget = QWidget()
  26.         central_widget.setLayout(layout)
  27.         self.setCentralWidget(central_widget)

  28.     def start_thread(self):
  29.         # 创建并配置任务对象
  30.         runnable = MyRunnable()
  31.         runnable.finished.connect(self.on_operation_finished)
  32.         
  33.         # 将任务提交给线程池
  34.         self.threadpool.start(runnable)

  35.     def on_operation_finished(self, exclude_rules):
  36.         # 在这里处理线程信号
  37.         print("操作完成:", exclude_rules)
  38.         # ...

  39. app = QApplication([])
  40. window_b = WindowB()
  41. window_b.show()
  42. app.exec()
复制代码


在这个示例中,我们定义了一个`MyRunnable`类,该类继承自`QRunnable`。在`run()`方法中编写了耗时的任务代码,并通过`finished`信号发射任务的结果。窗口B中的按钮方法`start_thread()`会创建并配置任务对象,然后将任务提交给线程池启动执行。当任务完成时,会触发信号`finished`,并在`on_operation_finished()`方法中处理任务的结果。

使用`QThreadPool`可以自动管理和调度多个任务的线程池,避免手动管理线程的复杂性。通过将任务对象提交给线程池,可以简化多线程的使用。希望这个解决方案能够帮助到你,如果还有其他问题,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-15 09:40:48 | 显示全部楼层
FishC 发表于 2024-3-15 09:17
如果你的窗口A已经关闭,并且所有的按钮和相关方法都在窗口B中,那么你可以将线程类定义在窗口B中,以 ...

那如果B窗体中有多个按钮、多个方法,又要怎么写呢?

麻烦示范一下。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-15 09:41:19 | 显示全部楼层
yxxxzx123 发表于 2024-03-15 09:40
那如果B窗体中有多个按钮、多个方法,又要怎么写呢?
...


如果窗口B中有多个按钮和多个方法,每个方法都需要在独立的线程中执行耗时任务,可以为每个按钮创建一个对应的槽函数,在槽函数中启动对应的线程来处理任务。以下是一个示例:from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLabelfrom PySide6.QtCore import QRunnable, QObject, Signal, Qt, QThreadPoolimport timeclass MyRunnable(QRunnable):    def __init__(self, task_name):        super().__init__()        self.task_name = task_name        self.setAutoDelete(True)    def run(self):        # 模拟耗时任务        time.sleep(3)        print(f"{self.task_name} 任务完成")        self.finished.emit()    finished = Signal()class WindowB(QMainWindow):    def __init__(self):        super().__init__()        self.threadpool = QThreadPool()                self.label = QLabel("进度条")        self.button1 = QPushButton("任务1")        self.button2 = QPushButton("任务2")        self.button1.clicked.connect(lambda: self.start_thread("任务1"))        self.button2.clicked.connect(lambda: self.start_thread("任务2"))        layout = QVBoxLayout()        layout.addWidget(self.label)        layout.addWidget(self.button1)        layout.addWidget(self.button2)        central_widget = QWidget()        central_widget.setLayout(layout)        self.setCentralWidget(central_widget)    def start_thread(self, task_name):        # 创建并配置任务对象        runnable = MyRunnable(task_name)        runnable.finished.connect(self.on_operation_finished)                # 将任务提交给线程池        self.threadpool.start(runnable)    def on_operation_finished(self):        # 在这里处理任务完成的操作        print("任务完成")app = QApplication()window_b = WindowB()window_b.show()app.exec()在这个示例中,我们为窗口B中的每个按钮创建了一个对应的槽函数,并通过`lambda`表达式将任务名称作为参数传递给`start_thread()`方法。`start_thread()`方法会根据任务名称创建并配置任务对象,并将任务提交给线程池。当任务完成时,会触发信号`finished`,在`on_operation_finished()`方法中处理任务的完成操作。通过这种方式,可以灵活地为窗口B中的多个按钮和方法启动不同的线程来执行耗时任务。希望这个示例能够解决你的问题,如果还有其他疑问,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-15 09:41:59 | 显示全部楼层
FishC 发表于 2024-3-15 09:41
如果窗口B中有多个按钮和多个方法,每个方法都需要在独立的线程中执行耗时任务,可以为每个按钮创建一 ...

回复请注意python格式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-15 09:50:21 | 显示全部楼层
FishC 发表于 2024-3-15 09:41
如果窗口B中有多个按钮和多个方法,每个方法都需要在独立的线程中执行耗时任务,可以为每个按钮创建一 ...

回复请注意python格式
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2024-3-15 09:51:11 | 显示全部楼层
FishC 发表于 2024-3-15 09:41
如果窗口B中有多个按钮和多个方法,每个方法都需要在独立的线程中执行耗时任务,可以为每个按钮创建一 ...

回复请注意python格式  麻烦也带上代码说明
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-15 09:51:33 | 显示全部楼层
yxxxzx123 发表于 2024-03-15 09:51
回复请注意python格式  麻烦也带上代码说明


非常抱歉,以下是使用Python格式的示例代码和详细说明:

  1. from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QPushButton, QLabel
  2. from PySide6.QtCore import QRunnable, QObject, Signal, Qt, QThreadPool
  3. import time

  4. class MyRunnable(QRunnable):
  5.     def __init__(self, task_name):
  6.         super().__init__()
  7.         self.task_name = task_name
  8.         self.setAutoDelete(True)

  9.     def run(self):
  10.         # 模拟耗时任务
  11.         time.sleep(3)
  12.         print(f"{self.task_name} 任务完成")
  13.         self.finished.emit()

  14.     finished = Signal()

  15. class WindowB(QMainWindow):
  16.     def __init__(self):
  17.         super().__init__()
  18.         self.threadpool = QThreadPool()
  19.         
  20.         self.label = QLabel("进度条")
  21.         self.button1 = QPushButton("任务1")
  22.         self.button2 = QPushButton("任务2")
  23.         
  24.         self.button1.clicked.connect(lambda: self.start_thread("任务1"))
  25.         self.button2.clicked.connect(lambda: self.start_thread("任务2"))
  26.         
  27.         layout = QVBoxLayout()
  28.         layout.addWidget(self.label)
  29.         layout.addWidget(self.button1)
  30.         layout.addWidget(self.button2)
  31.         
  32.         central_widget = QWidget()
  33.         central_widget.setLayout(layout)
  34.         self.setCentralWidget(central_widget)

  35.     def start_thread(self, task_name):
  36.         # 创建并配置任务对象
  37.         runnable = MyRunnable(task_name)
  38.         runnable.finished.connect(self.on_operation_finished)

  39.         # 将任务提交给线程池
  40.         self.threadpool.start(runnable)

  41.     def on_operation_finished(self):
  42.         # 在这里处理任务完成的操作
  43.         print("任务完成")

  44. app = QApplication()
  45. window_b = WindowB()
  46. window_b.show()
  47. app.exec()
复制代码


在这个示例中,我们创建了一个自定义的线程类`MyRunnable`,继承自`QRunnable`。在`MyRunnable`中,我们重写了`run()`方法,用于执行耗时任务。这里使用`time.sleep(3)`模拟了一个耗时3秒的任务。当任务完成后,通过发射信号`finished`来通知主线程。

在`WindowB`类中,我们创建了多个按钮和一个标签。为了演示不同按钮启动不同的线程,我们为每个按钮连接了对应的槽函数。在槽函数中,我们创建并配置了任务对象,并将任务提交给线程池进行执行。当任务完成时,会触发信号`finished`,在`on_operation_finished()`方法中处理任务完成的操作。

最后,我们创建了应用程序对象,实例化了窗口B并显示出来。

希望这个示例能够解决你的问题,如果还有其他疑问,请随时提问。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-15 09:51:46 | 显示全部楼层
AI不理我,真麻烦,要反复换号来问。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-15 10:25:31 | 显示全部楼层
FishC 发表于 2024-3-15 09:51
非常抱歉,以下是使用Python格式的示例代码和详细说明:

我没看懂,得慢慢消化。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-1 12:54

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表