PyQt5 QObject:无法为位于不同线程中的父级创建子级

2023-11-30

我正在使用 PyQt5 在菜单系统托盘中工作。我对 PyQt5 非常陌生,我想做的是在不阻止菜单的情况下触发操作(多线程)。在阅读了很多地方之后,我得出的结论是,使用Qthread应该是要走的路(但如果我能理解该类是如何工作的......)。然而,使用threading鉴于我的应用程序非常简单,也不会那么糟糕。所以,我尝试使用以下代码import threading:

from PyQt5 import QtCore, QtGui, QtWidgets
import threading

class menubar(object):
    def __init__(self):
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    self.systray = True
    self.stopped = False

    def search_menu(self):
        self.SearchAction = menu.addAction("Search")
        self.SearchAction.triggered.connect(self.search_cast)

    def _search_cast_(self):
        args.select_cc = True
        self.cc.initialize_cast()
        self.cast_list()

    def search_cast(self):
        threading.Thread(target=self._search_cast_).start()

#some more methods here...

def main():

    menubar()
    app = QtWidgets.QApplication(sys.argv)
    tray = QtWidgets.QSystemTrayIcon(icon)

    menu = QtWidgets.QMenu()
    start = menubar()
    start.search_menu()
    start.separator_menu()
    start.populating_menu()
    start.separator_menu()
    start.stop_menu()
    start.resetaudio_menu()
    start.about_menu()
    start.exit_menu()

    tray.setContextMenu(menu)
    tray.show()
    app.exec_()

if __name__ == '__main__':
     main()

当我启动菜单时,一切都按照我的预期就位。然后,当我点击菜单时Search该动作会触发self.search_cast方法,我的菜单中就会填充它找到的列表。我还可以看到我的应用程序在执行搜索时没有被阻止,但当它完成时,我收到以下错误:

QObject: Cannot create children for a parent that is in a different thread.
(Parent is QMenu(0x7fcef497c160), parent's thread is     QThread(0x7fcef2603d10), current thread is QThread(0x7fcef4a89360)
QObject: Cannot create children for a parent that is in a different thread.
(Parent is QMenu(0x7fcef497c160), parent's thread is  QThread(0x7fcef2603d10), current thread is QThread(0x7fcef4a89360)
QObject: Cannot create children for a parent that is in a different thread.

此后,菜单仍然是“功能性的”,因为它具有响应性,但无法触发更多操作。此外,似乎没有创建更多线程。如果有人能向我解释为什么会发生这种情况,我会很高兴?我看不到光...

Update:

我现在创建了一个worker.py其中包含:

from PyQt5.QtCore import QThread, QObject, pyqtSignal, pyqtSlot
#some other imports


class Worker(QObject):
    finished = pyqtSignal()


@pyqtSlot()
def _search_cast_(self):
    self.cc = casting()
    self.cc.initialize_cast()
    self.finished.emit()

然后我添加了class menubar下列:

class menubar(object):
    def __init__(self):
        self.cc = casting()
        signal.signal(signal.SIGINT, signal.SIG_DFL)
        self.cc.cast = None
        self.systray = True
        self.stopped = False

        self.obj = worker.Worker()  # no parent!
        self.thread = QThread()  # no parent!
        self.obj.moveToThread(self.thread)
        self.obj.finished.connect(self.thread.quit)
        self.thread.started.connect(self.obj._search_cast_)

  def search_menu(self):
        self.SearchAction = menu.addAction("Search")
        self.SearchAction.triggered.connect(self.search_cast)

  def search_cast(self):
    self.thread.start()
    self.cast_list()

  def cast_list(self):
     if len(self.cc.availablecc) == 0:
     # some actions here. 

现在我收到以下错误:

 AttributeError: 'casting' object has no attribute 'availablecc'

我确保实际上worker正在康复availablecc来自我调用的外部类cc。但由于某种原因没有被接收menubar班级。我正在基于此进行工作https://stackoverflow.com/a/33453124/1995261


由于这是此错误的谷歌最佳答案,并且我花了比预期更长的时间才能正确解决此问题,因此我将分享我针对 Python 3 和 PyQt 5 的非常简单的解决方案(如果您更改一些导入,它也应该在 PyQt4 中工作,我想)。

我遇到的情况是一个带有右键菜单的系统托盘图标,当不同的线程请求它时应该重新构建它。当然,您可以将其应用于您想要通过线程限制进行通信的其他问题。

import time
import sys
import threading
from PyQt5 import QtGui
from PyQt5 import QtWidgets
from PyQt5 import QtCore



class SystemTrayIcon(QtWidgets.QSystemTrayIcon):
    def __init__(self, icon=None, parent=None):
        icon = QtGui.QIcon(QtWidgets.QApplication.style().standardPixmap(QtWidgets.QStyle.SP_MediaPlay))
        QtWidgets.QSystemTrayIcon.__init__(self, icon, parent)

        self.menu = QtWidgets.QMenu(parent)
        self.setContextMenu(self.menu)

        self.build_menu()
        self.show()

        # see http://pyqt.sourceforge.net/Docs/PyQt5/signals_slots.html for more information
        self.signal = MySignal()
        self.signal.sig_no_args.connect(self.build_menu)
        self.signal.sig_with_str.connect(self.print_string)


    def build_menu(self):
        ''' This function should be called in order to rebuild 
        the right-click menu for the systray icon'''
        global list_dict_streams
        self.menu.clear()

        exitAction = self.menu.addAction("Exit")
        exitAction.triggered.connect(self._exit)

        for x in list_dict_streams :
            self.menu.addAction(x)


    def print_string(self, str):
        print(str)


    def _exit(self):
        QtCore.QCoreApplication.exit()



class MySignal(QtCore.QObject):
    ''' Why a whole new class? See here: 
    https://stackoverflow.com/a/25930966/2441026 '''
    sig_no_args = QtCore.pyqtSignal()
    sig_with_str = QtCore.pyqtSignal(str)


list_dict_streams = ["1"]
def work_thread(trayIcon):
    ''' Will add one menu item to the systray menu every 5 seconds
    and will send a signal with a string '''
    global list_dict_streams

    while True:
        trayIcon.signal.sig_no_args.emit()
        trayIcon.signal.sig_with_str.emit("String emitted")
        list_dict_streams.append(str(len(list_dict_streams)+1))
        time.sleep(5)


def main():
    app = QtWidgets.QApplication(sys.argv)
    trayIcon = SystemTrayIcon()

    t = threading.Thread(target=work_thread, args=(trayIcon,))
    t.daemon = True     # otherwise the 'Exit' from the systray menu will not work
    t.start()

    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

基本上你必须创建一个新的class MySignal(QtCore.QObject) why。我创建了一个包含两个示例的类 - 一个不发送任何参数,另一个可以传递字符串。你当然可以定义其他参数。然后在目标线程中创建此类的新实例,并将该类中的函数连接到目标内的函数(在我的例子中为系统托盘图标)。之后您现在可以致电emit(...)就像我在 while 循环中所做的那样。
现在 Qt 很高兴,因为与调用时相比,您只需发出一个信号trayIcon.build_menu()直接来自不同的线程。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PyQt5 QObject:无法为位于不同线程中的父级创建子级 的相关文章

  • Python Flask 删除请求

    我正在开发一个 Python 应用程序并使用 Flask 这是我的 DELETE 函数 app route DeleteMessage methods DELETE def DeleteMessage messages Message qu
  • 如何在redis中使用python删除排序集中的项目

    如何使用 python 删除排序集中大于某个值的项目 key foo pipe redis master conn pipeline pipe zadd key 1 a pipe zadd key 2 b pipe zadd key 3 c
  • Python:访问另一个类中一个类的属性和方法

    假设我有两个 A 类和 B 类 Class A A s attributes and methods here Class B B s attributes and methods here 现在我可以评估 B 类对象中 A 的属性 如下所
  • Python TypeError:不支持的操作数类型 -:“int”和“function”

    我是 Python 初学者 正在做一项作业 我不断得到TypeError unsupported operand type s for int and function 即使在研究了错误并应用了建议的修复之后 我并不是在寻找任何人给我一个解
  • 限制执行第三方软件的线程的权限

    我正在开发一个基于 Eclipse 的应用程序 能够执行第三方组件 不是 eclipse plugin 每个组件都有一个列出权限 以及相应动机 的自定义描述符 这样最终用户可以决定是否执行它 组件在单独的线程中执行 如何根据描述符限制这些线
  • Django表单中的隐藏字段不在cleaned_data中

    我有这个表格 class CollaboratorForm forms Form user forms CharField label Username max length 100 canvas forms IntegerField wi
  • 使用 Python 访问内存映射文件

    我希望利用激战 2 中的内存映射文件 该文件旨在链接到 Mumble 以获得位置音频 该文件包含有关字符坐标的信息和其他有用的信息 我已经能够使用此脚本访问坐标信息 import mmap import struct last while
  • 如何在Python中将N毫秒添加到日期时间

    我正在设置一个日期时间变量 fulldate datetime datetime strptime date time Y m d H M S f 其中日期和时间是适合日期时间性质的字符串 如何将此日期时间增加 N 毫秒 Use timed
  • 识别文本中的多个类别和相关情感

    如果您有一个文本语料库 如何识别所有类别 来自预定义类别列表 以及与之相关的情绪 正面 负面写作 我将在 Python 中执行此操作 但现阶段我不一定要寻找特定于语言的解决方案 让我们用一个例子来看看这个问题 试图澄清我的问题 如果我有一整
  • 构建wheel失败/“错误:INCLUDE环境变量为空”

    我正在使用 Python 2 7 11 并尝试 pip install 模块 但是其中一些模块失败了 我收到的消息是 无法为 X 构建轮子 和 错误 包含环境变量为空 我尝试安装 Scrapy LXML 和 Twisted 但都失败了 我尝
  • Python - 从一定范围内随机采样,同时避免某些值

    我一直在阅读有关random sample 函数在random模块 但没有看到任何可以解决我的问题的东西 我知道使用random sample range 1 100 5 会给我来自 人群 的 5 个独特样本 我想得到一个随机数range
  • matplotlib 后端 - 我关心吗?

    gt gt gt import matplotlib gt gt gt print matplotlib rcsetup all backends u GTK u GTKAgg u GTKCairo u MacOSX u Qt4Agg u
  • 如何让 Python 生成器返回 None 而不是 StopIteration?

    我使用生成器在列表中执行搜索 如下简单示例 gt gt gt a 1 2 3 4 gt gt gt i for i v in enumerate a if v 4 next 3 只是为了稍微说明一下示例 与上面的列表相比 我使用的列表要长得
  • Python pandas:向我的数据框中添加一列来计算变量

    我有一个像这样的数据框 gt org group org1 1 org2 1 org3 2 org4 3 org5 3 org6 3 我想将列 count 添加到 gt 数据帧以计算组的成员数量 预期结果如下 org group count
  • 为什么变量 1 += 变量 2 比变量 1 = 变量 1 + 变量 2 快得多?

    我继承了一些 Python 代码 用于创建巨大的表 最多 19 列宽 5000 行 花了九秒用于在屏幕上绘制表格 我注意到每一行都是使用以下代码添加的 sTable sTable n GetRow where sTable是一个字符串 我将
  • 从不同的线程访问对象

    我有一个服务器类 它基本上等待来自客户端的连接 在该类中 我创建了一个 NetworkStream 对象 以便能够从客户端接收字节 由于 NetworkStream Read 方法不是异步的 这意味着它将等到从客户端读取字节才能继续执行类似
  • 在 Python 中为非唯一列表创建虚拟列

    目前我有下一个数据框 import pandas as pd df pd DataFrame ID 1 2 3 4 5 col2 a b c c d e f f b f a c b b a b print df ID c
  • VSCode IntelliSense 认为 Python 'function()' 类存在

    VSCode IntelliSense 正在完成一个名为的 Python 类function 这似乎不存在 例如 这似乎是有效的代码 def foo value return function value foo 0 But functio
  • Java中ThreadFactory的使用

    有人可以简要解释一下如何以及何时使用 ThreadFactory 吗 使用和不使用 ThreadFactory 的示例可能确实有助于理解差异 Thanks 这是一种可能的用法 假设您有一个ExecutorService它执行你的Runnab
  • Mac 无法安装 Tensorflow

    我检查了我的 pip3 和 python3 版本 tensorflow MacBook Pro de Hector 2 tensorflow hectoresteban pip3 V pip 10 0 1 from Users hector

随机推荐

  • 学说实体关系

    我有一个实体模板和另一个请求 本质上 模板代表一个 html 表单 请求将代表表单填充的值的集合以及对模板 ID 的引用 class Request Id Column type integer GeneratedValue private
  • 安卓锁屏

    有没有办法在锁屏上显示文字 喜欢有关未读短信的信息或喜欢锁定屏幕上带有播放 暂停按钮的音乐播放器 Thanks 是的 也不是 他们没有公共 API 来创建或修改锁定屏幕 无论是谁在您的设备上构建了操作系统版本 都创建了您的锁定屏幕 一些制造
  • 如何使用 fastcgi_finish_request() 的示例

    有人可以展示一个关于如何使用的简单示例吗fastcgi finish request 功能 我用谷歌搜索 但只发现了一些一般性的提及 有些人说他们成功地使用了它 但我找不到带有代码的单个示例 例如 我有一个 PHP 对象 为了向浏览器发送响
  • 如何让Javascript忽略或保留空格,而不是删除它们

    我试图让一个函数用破折号覆盖多单词区域 但不用 JavaScript 中的破折号覆盖单词之间的空格 所以 我基本上需要 JS 来忽略空格 或者维护然后 但我在网上找到的只是如何从字符串中删除空格 如果我这样做 那么覆盖该区域的破折号之间仍然
  • jquery遍历查找父级的父级

    HTML li class comment div class p comm div class avatar img src img 1 jpg div div class c auth author a class del title
  • 如何从电子邮件地址中提取“域”

    我的专栏中有以下模式 email protected email protected 现在 我想在之后提取文本 和之前 即 gmail 和 hotmail 我能够在之后提取文本 用下面的代码 sub email 我如何修改上述内容以适合我的
  • 如何在 Marklogic 中构建一个简单的搜索应用程序?

    我想在 Marklogic 中构建一个简单的搜索应用程序 但我不想使用应用程序生成器 我想编写自己的 xqy 文件 我想从用户那里获取名字 姓氏和地址的输入 用户可以按名字 姓氏或地址进行搜索 他还可以通过输入所有三个字段来进行搜索 也可以
  • python 中的哨兵循环

    因此 我从用户那里获取要存储到列表中的输入 并且使用哨兵循环不断要求用户输入数字 出现的问题是 当用户完成输入值后 我使用 停止 结束循环时 出现错误 ValueError 以 10 为基数的 int 的文字无效 停止 我不知道为什么 如果
  • 按键对哈希值进行排序,然后在 Ruby 中返回哈希值

    这是对哈希进行排序并返回哈希对象 而不是数组 的最佳方法吗 h a gt 1 c gt 3 b gt 2 d gt 4 gt a gt 1 c gt 3 b gt 2 d gt 4 Hash h sort gt a gt 1 b gt 2
  • GWT 编译的一些微妙之处 - “gwt 模块可能需要(重新)编译。”

    我正在将应用程序部署到 GAE 我在 Eclipse 中设置了一个项目 其中包含三个独立的 GWT 模块 每个模块都有自己的 HTML 页面 入口点等 它们共享大量代码 当我将应用程序部署到 appengine 时 其中两个模块工作正常 我
  • getstream.io 中的用户身份验证和配置文件

    我想知道是否可以直接使用 getstream io 管理用户配置文件和用户身份验证 我浏览了示例 但不明白用户是如何创建的 目前无法在 Stream 中管理用户帐户 配置文件和身份验证 Stream 最好与处理这些事情和其他功能 应用程序逻
  • OpenCV、Qt、imread、namedWindow、imshow 不起作用

    In the pro file QT core QT gui TARGET latihan 2 CONFIG console CONFIG app bundle TEMPLATE app SOURCES main cpp INCLUDEPA
  • 有人对 Play 框架有什么好的 A/B 测试策略吗?

    我对好的策略感兴趣A B 或拆分测试与 Play 框架 显而易见的选择是使用 Google 网站优化工具 但出于以下几个原因我不想这样做 只允许您测试表示层中的内容 很难根据收入等因素 而不是点击或转化等二元事件 进行测试 不得不用 Jav
  • 在 Click 事件上查找按钮的父 ListViewItem

    我有一个按钮作为每个 ListViewItem 的最后一列 当按下按钮时 我需要在单击事件中找到按钮 发送者 父列表视图项 我努力了 ListViewItem itemToCancel sender as System Windows Co
  • 通过指向派生类的基指针增强序列化[重复]

    这个问题在这里已经有答案了 可能的重复 使用多态档案增强序列化 我试图使用指向派生类的基指针来序列化我的类 但这仅序列化基类 我刚刚读过http www boost org doc libs 1 32 0 libs serializatio
  • contextMenu 破坏 FullCalendar 事件拖动

    因此 我最近使用 jQuery contextMenu http abeautifulsite net blog 2008 09 jquery context menu plugin 在 FullCalendar 中的事件中添加了一个上下文
  • .Net 中“InvokeRequired”和“Invoke”是什么意思?

    我在我正在开发的几个程序中做了很多线程方面的工作 并且我一直很好奇到底有些东西在做什么 以以下代码为例 该代码从线程运行以更新 UI Public Sub UpdateGrid If Me InvokeRequired Then Me In
  • iPhone 应用程序本地化,针对不同市场发布单独的应用程序

    我在瑞典应用商店上有一个应用程序 我打算将其适应其他一些市场 在这种情况下 本地化最重要的部分是改变应用程序针对不同市场 国家 的工作方式的某些方面 因此这主要不是语言适应 也许 我不会使用正常的内置机制进行本地化 相反 我考虑为不同的市场
  • System.OutOfMemoryException - 当实体框架查询 Varbinary 类型的太大数据时

    我正在尝试查询varbinary包含文件 1 2 Gb 的列 我正在使用实体框架 见下文 要测试的数据库 CREATE TABLE dbo BIGDATA id bigint IDENTITY 1 1 NOT NULL BIGDATA va
  • PyQt5 QObject:无法为位于不同线程中的父级创建子级

    我正在使用 PyQt5 在菜单系统托盘中工作 我对 PyQt5 非常陌生 我想做的是在不阻止菜单的情况下触发操作 多线程 在阅读了很多地方之后 我得出的结论是 使用Qthread应该是要走的路 但如果我能理解该类是如何工作的 然而 使用th