鱼C论坛

 找回密码
 立即注册
查看: 787|回复: 23

开户线程后报错。

[复制链接]
发表于 2024-3-17 08:17:08 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
现有如下代码:

self.textEdit_5.setReadOnly(True)

按钮点击:
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 = "123.xls"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = xlrd.open_workbook(file_path)
        else:
            file_name = "123.xlsx"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = load_workbook(file_path)

       此时我打开self.textEdit_5想录入数据:
        self.textEdit_5.setReadOnly(False)

        
        for sheet_name in Exclud_Book.sheet_names():
           
            exclude_rows_input = input()
            if exclude_rows_input:
                self.exclude_rows = [int(row) - 1 for row in exclude_rows_input.split(',')]

            
            exclude_cols_input = input()
            if exclude_cols_input:
                exclude_cols = [convert_position(col) for col in exclude_cols_input.split(',')]

            exclude_rules[sheet_name] = {'1': exclude_rows, '2': exclude_cols}
           
        print(exclude_rules)



然后就报错:
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 "C:\Users\ynyxs\Desktop\20240316\xtt031600.py", line 1080, in run
    self.textEdit_5.setReadOnly(False)
    ^^^^^^^^^^^^^^^
AttributeError: 'MyThread' object has no attribute 'textEdit_5'


请问是什么原因?

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2024-3-17 08:17:16 | 显示全部楼层
报错原因是 'MyThread' 对象没有 'textEdit_5' 属性。这是因为在 MyThread 类中,它不知道关于界面窗口的任何信息。解决这个问题的一个方法是将界面窗口实例作为参数传递给 MyThread 类。

首先,在 `start_thread` 方法中创建 MyThread 对象时,将 self 作为参数传递给它:
thread = MyThread(file_type, self.File_Path, self)

然后,在 MyThread 类中,修改 `__init__` 方法,接收一个额外的参数 window,并将其存储为实例属性:
def __init__(self, file_type, file_path, window):
    super().__init__()
    self.File_Type = file_type
    self.File_Path = file_path
    self.window = window

接下来,在 run 方法中,使用 self.window.textEdit_5 来访问界面窗口的 textEdit_5 对象:
self.window.textEdit_5.setReadOnly(False)

这样就可以避免报错了。

另外,你在 for 循环中使用了 input() 函数来获取用户输入,但是并没有将其赋值给相应的变量(比如 exclude_rows 和 exclude_cols),请确保正确赋值后再使用这些变量。

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

使用道具 举报

 楼主| 发表于 2024-3-17 08:28:49 | 显示全部楼层
FishC 发表于 2024-3-17 08:17
报错原因是 'MyThread' 对象没有 'textEdit_5' 属性。这是因为在 MyThread 类中,它不知道关于界面窗口的任 ...

我一共有3个window:
class BaseWindow(QWidget):
    def __init__(self):
        super().__init__()

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

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


self.textEdit_5是放在WindowB中,但是我把你教我的改成下面这样:

class MyThread(threading.Thread):
    # 在 MyThread 类中,修改 `__init__` 方法,接收File_Path和window,并将其存储为实例属性:
    def __init__(self, file_type, file_path, windowB):
        super().__init__()
        self.File_Type = file_type
        self.File_Path = file_path
        self.window = windowB

还是报错:

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 "C:\Users\ynyxs\Desktop\20240316\xtt031600.py", line 1082, in run
    self.textEdit_5.setReadOnly(False)
    ^^^^^^^^^^^^^^^
AttributeError: 'MyThread' object has no attribute 'textEdit_5'


请问是什么原因?





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

使用道具 举报

发表于 2024-3-17 08:29:02 | 显示全部楼层
凊风 发表于 2024-03-17 08:28
我一共有3个window:
class BaseWindow(QWidget):
   ...


报错的原因是 `MyThread` 类仍然没有 `textEdit_5` 属性,因为你在 `MyThread` 类中存储了 `windowB`,但是没有将其与 `textEdit_5` 关联起来。

为了解决这个问题,你可以将 `textEdit_5` 作为参数传递给 `MyThread` 类,并在初始化方法中将其存储为实例属性。修改如下:
class MyThread(threading.Thread):
    def __init__(self, file_type, file_path, windowB, textEdit_5):
        super().__init__()
        self.File_Type = file_type
        self.File_Path = file_path
        self.window = windowB
        self.textEdit_5 = textEdit_5

    def run(self):
        self.textEdit_5.setReadOnly(False)
        # 其他代码省略

然后,在创建 `MyThread` 对象时,将 `textEdit_5` 参数传递给它:
thread = MyThread(file_type, self.File_Path, self, self.textEdit_5)

这样就能够正确地访问 `textEdit_5` 属性了。记得在其他用到 `textEdit_5` 的地方也要做相应的修改。

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

使用道具 举报

 楼主| 发表于 2024-3-17 10:43:59 | 显示全部楼层
FishC 发表于 2024-3-17 08:29
报错的原因是 `MyThread` 类仍然没有 `textEdit_5` 属性,因为你在 `MyThread` 类中存储了 `windowB`, ...

照这样计算,那我WindowB有多少控件就得这样全部传递吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-17 10:44:28 | 显示全部楼层
凊风 发表于 2024-03-17 10:43
照这样计算,那我WindowB有多少控件就得这样全部传递 ...


是的,如果你想在 `MyThread` 类中访问 `WindowB` 中的多个控件,那么你需要将这些控件都作为参数传递给 `MyThread` 类,并在初始化方法中将它们存储为实例属性。这是因为线程是独立于界面的,并且不能直接访问界面的控件。

然而,如果你有许多控件需要在线程中使用,手动一个一个传递可能会变得很麻烦。一种更好的解决办法是使用信号(signal)和槽(slot)机制来进行线程与界面之间的通信。

具体来说,你可以通过定义自定义信号,在 `MyThread` 类中发射信号,然后在 `WindowB` 类中连接信号和相应的槽函数。这样,当线程中的事件发生时,信号会触发槽函数在界面中执行相应的操作。

以下是一个简单的示例代码:
from PyQt5.QtCore import QObject, pyqtSignal, QThread

class Worker(QObject):
    finished = pyqtSignal()  # 自定义信号,用于通知界面线程完成工作

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

    def run(self):
        # 线程执行的耗时任务
        # ...

        self.finished.emit()  # 发射信号,通知界面线程任务完成

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

        self.textEdit_5 = QTextEdit(self)
        self.pushButton_3 = QPushButton("Start", self)

        self.pushButton_3.clicked.connect(self.start_thread)

    def start_thread(self):
        self.textEdit_5.setReadOnly(True)  # 在开始线程前禁用控件

        self.worker = Worker()
        self.worker.finished.connect(self.thread_finished)

        self.thread = QThread()
        self.worker.moveToThread(self.thread)

        self.thread.started.connect(self.worker.run)
        self.thread.finished.connect(self.thread.deleteLater)  # 线程结束后自动删除
        self.thread.finished.connect(self.worker.deleteLater)  # 工作对象结束后自动删除
        self.thread.finished.connect(self.thread_finished)  # 线程结束后执行线程结束处理

        self.thread.start()

    def thread_finished(self):
        self.textEdit_5.setReadOnly(False)  # 线程结束后启用控件

在这个示例中,我们定义了一个 `Worker` 类作为工作线程的实际执行者,并发射了一个信号 `finished`。在 `WindowB` 类中,我们连接了 `QPushButton` 的点击事件与 `start_thread` 槽函数,并在该函数中创建了工作线程 `worker` 和线程 `thread`,并将 `finished` 信号连接到 `thread_finished` 槽函数。

当点击按钮触发 `start_thread` 函数时,`textEdit_5` 控件被禁用。工作线程在独立的线程中执行耗时任务,并在任务完成后发射信号 `finished`。`thread_finished` 槽函数会在信号触发后被调用,其中可以进行界面的相关操作,比如启用 `textEdit_5` 控件。

这样,通过使用信号和槽机制,你可以更方便地实现线程与界面之间的通信,而不需要将所有控件都手动传递给线程类。

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

使用道具 举报

 楼主| 发表于 2024-3-17 10:52:40 | 显示全部楼层
本帖最后由 凊风 于 2024-3-17 10:54 编辑
FishC 发表于 2024-3-17 10:44
是的,如果你想在 `MyThread` 类中访问 `WindowB` 中的多个控件,那么你需要将这些控件都作为参数传递 ...


我用的是PySide6,并且各个控件(比如说有6个按钮)执行的任务都不相同,又要怎么处理呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-17 10:53:23 | 显示全部楼层
凊风 发表于 2024-03-17 10:52
我用的是PySide6,并且各个控件执行的任务都不相同, ...


在 PySide6 中,也可以使用信号和槽机制来实现线程与界面之间的通信。每个控件执行不同任务的情况下,你可以定义多个自定义信号,并在 `MyThread` 类中发射不同的信号来通知界面执行相应的操作。以下是一个示例代码:from PySide6.QtCore import Signal, QObject, QThreadclass Worker(QObject):    # 定义多个自定义信号,用于不同任务的通知    finished_task1 = Signal(int)    finished_task2 = Signal(str)    def __init__(self):        super().__init__()    def task1(self):        # 执行任务1的代码        result = 100        self.finished_task1.emit(result)  # 发射任务1完成的信号    def task2(self):        # 执行任务2的代码        result = "Hello World"        self.finished_task2.emit(result)  # 发射任务2完成的信号class WindowB(BaseWindow):    def __init__(self):        super().__init__()        self.textEdit_5 = QTextEdit(self)        self.pushButton_3 = QPushButton("Start Task 1", self)        self.pushButton_4 = QPushButton("Start Task 2", self)        self.pushButton_3.clicked.connect(self.start_thread_task1)        self.pushButton_4.clicked.connect(self.start_thread_task2)    def start_thread_task1(self):        self.textEdit_5.setReadOnly(True)  # 在开始线程前禁用控件        self.worker = Worker()        self.worker.finished_task1.connect(self.thread_finished_task1)        self.thread = QThread()        self.worker.moveToThread(self.thread)        self.thread.started.connect(self.worker.task1)        self.thread.finished.connect(self.thread.deleteLater)  # 线程结束后自动删除        self.thread.finished.connect(self.worker.deleteLater)  # 工作对象结束后自动删除        self.thread.start()    def start_thread_task2(self):        self.textEdit_5.setReadOnly(True)  # 在开始线程前禁用控件        self.worker = Worker()        self.worker.finished_task2.connect(self.thread_finished_task2)        self.thread = QThread()        self.worker.moveToThread(self.thread)        self.thread.started.connect(self.worker.task2)        self.thread.finished.connect(self.thread.deleteLater)  # 线程结束后自动删除        self.thread.finished.connect(self.worker.deleteLater)  # 工作对象结束后自动删除        self.thread.start()    def thread_finished_task1(self, result):        self.textEdit_5.setPlainText(str(result))  # 在界面上显示任务1的结果        self.textEdit_5.setReadOnly(False)  # 线程结束后启用控件    def thread_finished_task2(self, result):        self.textEdit_5.append(result)  # 在界面上显示任务2的结果        self.textEdit_5.setReadOnly(False)  # 线程结束后启用控件在这个示例中,我们定义了一个 `Worker` 类作为工作线程的实际执行者,并定义了两个不同的自定义信号 `finished_task1` 和 `finished_task2`。在 `WindowB` 类中,我们连接了两个 `QPushButton` 的点击事件与相应的槽函数 `start_thread_task1` 和 `start_thread_task2`。在这两个槽函数中,我们创建了不同的工作线程 `worker` 和线程 `thread`,并将相应的自定义信号连接到界面的槽函数 `thread_finished_task1` 和 `thread_finished_task2`。当点击按钮触发相应的槽函数时,`textEdit_5` 控件被禁用。在各自的工作线程中,执行任务1和任务2的代码,并通过发射对应的自定义信号,将结果传递给界面。在界面的槽函数中,你可以根据不同的任务结果,执行相应的操作,比如更新 `textEdit_5` 控件的内容。这样,你可以根据不同的任务类型和结果,实现线程与界面之间的通信和协作。

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

使用道具 举报

 楼主| 发表于 2024-3-17 10:54:38 | 显示全部楼层
FishC 发表于 2024-3-17 10:53
在 PySide6 中,也可以使用信号和槽机制来实现线程与界面之间的通信。每个控件执行不同任务的情况下, ...

我用的是PySide6,并且各个控件(比如说有6个按钮)执行的任务都不相同,又要怎么处理呢?

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

使用道具 举报

发表于 2024-3-17 10:54:53 | 显示全部楼层
凊风 发表于 2024-03-17 10:54
我用的是PySide6,并且各个控件(比如说有6个按钮)执 ...


在PySide6中,可以通过使用lambda表达式和信号参数来处理多个控件执行不同任务的情况。以下是一个示例代码:
from PySide6.QtWidgets import QMainWindow, QPushButton, QApplication

class MyWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.button1 = QPushButton("Task 1", self)
        self.button2 = QPushButton("Task 2", self)
        self.button3 = QPushButton("Task 3", self)
        # ... 添加其他按钮

        self.button1.clicked.connect(lambda: self.start_task(1))
        self.button2.clicked.connect(lambda: self.start_task(2))
        self.button3.clicked.connect(lambda: self.start_task(3))
        # ... 连接其他按钮的点击事件

    def start_task(self, task_number):
        if task_number == 1:
            # 执行任务1的代码
            print("执行任务1")
        elif task_number == 2:
            # 执行任务2的代码
            print("执行任务2")
        elif task_number == 3:
            # 执行任务3的代码
            print("执行任务3")
        # ... 添加其他任务的代码

if __name__ == "__main__":
    app = QApplication()
    window = MyWindow()
    window.show()
    app.exec()

在上面的示例中,我们创建了一个`MyWindow`类继承自`QMainWindow`,并添加了6个按钮(这里为了简洁起见只展示了3个按钮)。每个按钮通过`clicked`信号连接到`start_task`方法,同时传递不同的任务编号。

在`start_task`方法中,根据任务编号的不同,执行相应的任务代码。你可以在每个分支中编写对应的任务逻辑。

通过使用lambda表达式和信号参数,我们可以轻松处理多个控件执行不同任务的情况,而无需为每个按钮编写单独的槽函数。

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

使用道具 举报

 楼主| 发表于 2024-3-17 10:57:07 | 显示全部楼层
FishC 发表于 2024-3-17 10:54
在PySide6中,可以通过使用lambda表达式和信号参数来处理多个控件执行不同任务的情况。以下是一个示例 ...

可能我没表达清楚,我重新开贴来问。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-17 10:57:14 | 显示全部楼层
凊风 发表于 2024-03-17 10:57
可能我没表达清楚,我重新开贴来问。


好的,欢迎重新提问。请告诉我你在PySide6中遇到的问题,我将尽力帮你解答。

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

使用道具 举报

 楼主| 发表于 2024-3-17 11:11:53 | 显示全部楼层
FishC 发表于 2024-3-17 10:44
是的,如果你想在 `MyThread` 类中访问 `WindowB` 中的多个控件,那么你需要将这些控件都作为参数传递 ...

这里没看到`MyThread` 类啊。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-17 11:12:21 | 显示全部楼层
凊风 发表于 2024-03-17 11:11
这里没看到`MyThread` 类啊。。。。


非常抱歉,之前的回答中使用的是 PyQt5 的示例代码。如果你使用的是 PySide2,可以按照以下方式实现线程和界面之间的通信:
from PySide2.QtCore import QObject, Signal, QThread

class Worker(QObject):
    finished = Signal()  # 自定义信号,用于通知界面线程完成工作

    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 = "123.xls"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = xlrd.open_workbook(file_path)
        else:
            file_name = "123.xlsx"
            # 拼接文件路径
            file_path = os.path.join(self.File_Path, file_name)
            Exclud_Book = load_workbook(file_path)

        # 进行其他耗时操作
        # ...

        self.finished.emit()  # 发射信号,通知界面线程任务完成

在 `Worker` 类中,我们定义了一个 `finished` 信号并继承自 `QObject`,这样我们就可以在其中定义和发射信号。在 `run` 方法中,你可以进行耗时的操作,例如打开和处理 Excel 文件。当任务完成后,我们发射 `finished` 信号。

接下来,在 `WindowB` 类中的 `start_thread` 方法中,连接了 `Worker` 对象的 `finished` 信号到槽函数 `thread_finished`:
class WindowB(BaseWindow):
    def __init__(self):
        super().__init__()
        self.textEdit_5 = QTextEdit(self)
        self.pushButton_3 = QPushButton("Start", self)
        self.pushButton_3.clicked.connect(self.start_thread)

    def start_thread(self):
        self.textEdit_5.setReadOnly(True)  # 在开始线程前禁用控件

        file_type = 'xls'  # 假设这是你的文件类型
        file_path = 'path/to/file'  # 假设这是你的文件路径

        self.worker = Worker(file_type, file_path)
        self.worker.finished.connect(self.thread_finished)

        self.thread = QThread()
        self.worker.moveToThread(self.thread)

        self.thread.started.connect(self.worker.run)
        self.thread.finished.connect(self.thread.deleteLater)  # 线程结束后自动删除
        self.thread.finished.connect(self.worker.deleteLater)  # 工作对象结束后自动删除
        self.thread.finished.connect(self.thread_finished)  # 线程结束后执行线程结束处理

        self.thread.start()

    def thread_finished(self):
        self.textEdit_5.setReadOnly(False)  # 线程结束后启用控件

在 `start_thread` 方法中,创建了一个 `Worker` 类的实例 `worker`,并将其 `finished` 信号连接到 `thread_finished` 槽函数。然后,创建了一个 `QThread` 实例 `thread`,并将 `worker` 移动到 `thread` 中执行。

最后,我们连接了 `thread` 的 `started` 信号到 `worker` 的 `run` 方法,连接了 `thread` 的 `finished` 信号到一些清理操作,并连接了 `thread` 的 `finished` 信号到 `thread_finished` 槽函数。

当点击按钮触发 `start_thread` 方法时,`textEdit_5` 控件将被禁用。然后,工作线程会在独立的线程中执行耗时任务,在任务完成后发射 `finished` 信号。最终,`thread_finished` 槽函数会被调用,你可以在其中进行界面的相关操作,例如启用 `textEdit_5` 控件。

请注意,这里的示例代码是使用 PySide2 实现的。如果你使用的是 PyQt5,你需要相应地导入和使用 PyQt5 的类和模块。

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

使用道具 举报

 楼主| 发表于 2024-3-17 11:15:01 | 显示全部楼层
FishC 发表于 2024-3-17 11:12
非常抱歉,之前的回答中使用的是 PyQt5 的示例代码。如果你使用的是 PySide2,可以按照以下方式实现线 ...

我用的是PySide6,并且窗体B中有6个按钮,各个按钮的功能又不相同,请问要如何 处理呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-17 11:15:19 | 显示全部楼层
凊风 发表于 2024-03-17 11:15
我用的是PySide6,并且窗体B中有6个按钮,各个按钮的功 ...


如果窗体B中的按钮具有不同的功能,你可以根据每个按钮的点击事件单独处理。以下是一个示例代码,展示了如何在窗体B中处理多个按钮的点击事件:
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton


class WindowB(QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.setup_ui()
        
    def setup_ui(self):
        self.setWindowTitle("Window B")
        
        self.button_1 = QPushButton("Button 1", self)
        self.button_1.clicked.connect(self.on_button_1_clicked)
        
        self.button_2 = QPushButton("Button 2", self)
        self.button_2.clicked.connect(self.on_button_2_clicked)
        
        self.button_3 = QPushButton("Button 3", self)
        self.button_3.clicked.connect(self.on_button_3_clicked)
        
        self.button_4 = QPushButton("Button 4", self)
        self.button_4.clicked.connect(self.on_button_4_clicked)
        
        self.button_5 = QPushButton("Button 5", self)
        self.button_5.clicked.connect(self.on_button_5_clicked)
        
        self.button_6 = QPushButton("Button 6", self)
        self.button_6.clicked.connect(self.on_button_6_clicked)
        
    def on_button_1_clicked(self):
        # 处理按钮1的点击事件
        print("Button 1 clicked")
        
    def on_button_2_clicked(self):
        # 处理按钮2的点击事件
        print("Button 2 clicked")
        
    def on_button_3_clicked(self):
        # 处理按钮3的点击事件
        print("Button 3 clicked")
        
    def on_button_4_clicked(self):
        # 处理按钮4的点击事件
        print("Button 4 clicked")
        
    def on_button_5_clicked(self):
        # 处理按钮5的点击事件
        print("Button 5 clicked")
        
    def on_button_6_clicked(self):
        # 处理按钮6的点击事件
        print("Button 6 clicked")


app = QApplication([])
window_b = WindowB()
window_b.show()
app.exec()

在上面的示例代码中,我们创建了一个名为`WindowB`的窗口类,并为每个按钮创建了一个点击事件处理函数。你可以根据实际需求修改每个按钮的点击事件处理代码,以实现不同的功能。在每个点击事件处理函数中,你可以执行特定的操作,例如启动线程、打开对话框、更新界面等。

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

使用道具 举报

 楼主| 发表于 2024-3-17 11:20:36 | 显示全部楼层
FishC 发表于 2024-3-17 11:15
如果窗体B中的按钮具有不同的功能,你可以根据每个按钮的点击事件单独处理。以下是一个示例代码,展示 ...

为了防止程序 卡死,需要开启多线程。。。。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2024-3-17 11:20:57 | 显示全部楼层
凊风 发表于 2024-03-17 11:20
为了防止程序 卡死,需要开启多线程。。。。


如果你想在窗体B中处理按钮点击事件时使用多线程,以防止程序卡死,可以考虑使用`QThread`来创建多线程。以下是一个示例代码,展示了如何在窗体B中使用多线程处理按钮点击事件:from PySide6.QtWidgets import QApplication, QMainWindow, QPushButtonfrom PySide6.QtCore import QThread, Signalclass WorkerThread(QThread):    finished = Signal()  # 自定义信号,在线程完成后发送    def __init__(self, button_id):        super().__init__()        self.button_id = button_id    def run(self):        # 执行耗时的操作(这里仅作示例)        for i in range(5):            print(f"Button {self.button_id} clicked, iteration {i+1}")            self.sleep(1)        self.finished.emit()  # 发送信号表示线程完成class WindowB(QMainWindow):    def __init__(self):        super().__init__()        self.setup_ui()    def setup_ui(self):        self.setWindowTitle("Window B")        self.buttons = []        for i in range(6):            button = QPushButton(f"Button {i+1}", self)            button.clicked.connect(self.on_button_clicked)            self.buttons.append(button)    def on_button_clicked(self):        button_id = self.buttons.index(self.sender())        worker = WorkerThread(button_id)  # 创建工作线程        worker.finished.connect(self.on_worker_finished)  # 绑定线程完成信号        worker.start()  # 启动工作线程    def on_worker_finished(self):        print("Worker finished")app = QApplication([])window_b = WindowB()window_b.show()app.exec()在上面的示例代码中,我们创建了一个名为`WorkerThread`的子类,继承自`QThread`,用于执行耗时的操作。在`WorkerThread`的`run`方法中,我们模拟了一个耗时操作(这里只是简单地打印信息并暂停1秒)。当线程完成后,它会发出`finished`信号。在`WindowB`类中,我们在每个按钮的点击事件处理函数`on_button_clicked`中创建了一个`WorkerThread`对象,并启动它。同时,我们将线程的`finished`信号与槽函数`on_worker_finished`进行了连接。一旦线程完成,就会触发`on_worker_finished`槽函数。你可以根据实际需求,在`on_worker_finished`槽函数中执行适当的操作,例如更新界面或执行其他任务。使用多线程可以确保按钮点击事件的处理在后台执行,不会阻塞主线程,从而避免程序卡死的情况。

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

使用道具 举报

 楼主| 发表于 2024-3-17 11:24:58 | 显示全部楼层
FishC 发表于 2024-3-17 11:20
如果你想在窗体B中处理按钮点击事件时使用多线程,以防止程序卡死,可以考虑使用`QThread`来创建多线程 ...

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

使用道具 举报

发表于 2024-3-17 11:31:25 | 显示全部楼层
凊风 发表于 2024-03-17 11:24
回复请注意python格式


非常抱歉,我将以正确的 Python 格式重新给出示例代码:
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton
from PySide6.QtCore import QThread, Signal

class WorkerThread(QThread):
    finished = Signal()  # 自定义信号,在线程完成后发送

    def __init__(self, button_id):
        super().__init__()
        self.button_id = button_id

    def run(self):
        # 执行耗时的操作(这里仅作示例)
        for i in range(5):
            print(f"Button {self.button_id} clicked, iteration {i+1}")
            self.sleep(1)
        self.finished.emit()  # 发送信号表示线程完成

class WindowB(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setup_ui()

    def setup_ui(self):
        self.setWindowTitle("Window B")
        self.buttons = []
        for i in range(6):
            button = QPushButton(f"Button {i+1}", self)
            button.clicked.connect(self.on_button_clicked)
            self.buttons.append(button)

    def on_button_clicked(self):
        button_id = self.buttons.index(self.sender())
        worker = WorkerThread(button_id)  # 创建工作线程
        worker.finished.connect(self.on_worker_finished)  # 绑定线程完成信号
        worker.start()  # 启动工作线程

    def on_worker_finished(self):
        print("Worker finished")

app = QApplication()
window_b = WindowB()
window_b.show()
app.exec()

希望这次的示例代码更符合 Python 的格式要求。如果还有其他问题,请随时提问。

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

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-9-22 10:34

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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