为什么我的 QThread 持续使 Maya 崩溃?

2024-03-26

我有一个 UI,我想在 Maya 内部使用线程。这样做的原因是这样我可以运行 Maya.cmds,而无需挂起/冻结 UI,同时使用进度条等更新 UI。

我已经阅读了 StackOverflow 中的一些示例,但我的代码每次运行时都会崩溃。我遵循的例子是here https://stackoverflow.com/questions/56629553/proper-pyside-qthread-use-in-maya-to-avoid-hard-crash and here https://stackoverflow.com/questions/37687463/single-worker-thread-for-all-tasks-or-multiple-specific-workers/37688544#37688544

import maya.cmds as cmds
from PySide2 import QtWidgets, QtCore, QtGui, QtUiTools
import mainWindow #Main window just grabs the Maya main window and returns the object to use as parent.

class Tool(QtWidgets.QMainWindow):
    def __init__(self, parent=mainWindow.getMayaMainWindow()):
        super(Tool, self).__init__(parent)

        UI = "pathToUI/UI.ui"
        loader = QtUiTools.QUiLoader()
        ui_file = QtCore.QFile(UI)
        ui_file.open(QtCore.QFile.ReadOnly)
        self.ui = loader.load(ui_file, self)

        #Scans all window objects and if one is open with the same name as this tool then close it so we don't have two open.
        mainWindow.closeUI("Tool")      

        ###HERE'S WHERE THE THREADING STARTS###
        #Create a thread
        thread = QtCore.QThread()
        #Create worker object
        self.worker = Worker()
        #Move worker object into thread (This creates an automatic queue if multiples of the same worker are called)
        self.worker.moveToThread(thread)

        #Connect buttons in the UI to trigger a method inside the worker which should run in a thread
        self.ui.first_btn.clicked.connect(self.worker.do_something)
        self.ui.second_btn.clicked.connect(self.worker.do_something_else)
        self.ui.third_btn.clicked.connect(self.worker.and_so_fourth)

        #Start the thread
        thread.start()

        #Show UI
        self.ui.show()

class Worker(QtCore.QObject):
    def __init__(self):
        super(Worker, self).__init__() #This will immediately crash Maya on tool launch
        #super(Worker).__init__() #This works to open the window but still gets an error '# TypeError: super() takes at least 1 argument (0 given)'

    def do_something(self):
        #Start long code here and update progress bar as needed in a still active UI.
        myTool.ui.progressBar.setValue(0)
        print "doing something!"
        myTool.ui.progressBar.setValue(100)

    def do_something_else(self):
        #Start long code here and update progress bar as needed in a still active UI.
        myTool.ui.progressBar.setValue(0)
        print "doing something else!"
        myTool.ui.progressBar.setValue(100)

    def and_so_fourth(self):
        #Start long code here and update progress bar as needed in a still active UI.
        myTool.ui.progressBar.setValue(0)
        print "and so fourth, all in the new thread in a queue of which method was called first!"
        myTool.ui.progressBar.setValue(100)

#A Button inside Maya will import this code and run the 'launch' function to setup the tool
def launch():
    global myTool
    myTool = Tool()

我期望 UI 保持活动状态(未锁定)并且线程运行 Maya cmd,而在更新 UI 进度条时不会使 Maya 完全崩溃。

对此的任何见解都会令人惊奇!


据我所知,它有以下错误:

  • thread是一个局部变量,当构造函数执行完成时被删除,导致执行的内容在主线程中完成,这是不希望的,解决方案是延长生命周期,为此有几种解决方案:1)制作类属性,2)将父级传递给由父级管理的生命周期。在这种情况下,请使用第二种解决方案。

  • 您不应该从另一个线程修改 GUI,如果您已经修改了progressBar从另一个线程,在 Qt 中你必须使用信号。

  • 您必须在另一个线程中执行的方法中使用 @Slot 装饰器。

  • 您表明您要修改myTool但你还没有声明它,所以global myTool不会通过使工作myTool要删除的局部变量。解决方案是声明myTool:myTool = None综合以上情况,解决方案是:

import maya.cmds as cmds
from PySide2 import QtWidgets, QtCore, QtGui, QtUiTools
import mainWindow  # Main window just grabs the Maya main window and returns the object to use as parent.


class Tool(QtWidgets.QMainWindow):
    def __init__(self, parent=mainWindow.getMayaMainWindow()):
        super(Tool, self).__init__(parent)

        UI = "pathToUI/UI.ui"
        loader = QtUiTools.QUiLoader()
        ui_file = QtCore.QFile(UI)
        ui_file.open(QtCore.QFile.ReadOnly)
        self.ui = loader.load(ui_file, self)

        # Scans all window objects and if one is open with the same name as this tool then close it so we don't have two open.
        mainWindow.closeUI("Tool")

        # Create a thread
        thread = QtCore.QThread(self)
        # Create worker object
        self.worker = Worker()
        # Move worker object into thread (This creates an automatic queue if multiples of the same worker are called)
        self.worker.moveToThread(thread)

        # Connect buttons in the UI to trigger a method inside the worker which should run in a thread
        self.ui.first_btn.clicked.connect(self.worker.do_something)
        self.ui.second_btn.clicked.connect(self.worker.do_something_else)
        self.ui.third_btn.clicked.connect(self.worker.and_so_fourth)

        self.worker.valueChanged.connect(self.ui.progressBar.setValue)

        # Start the thread
        thread.start()

        # Show UI
        self.ui.show()


class Worker(QtCore.QObject):
    valueChanged = QtCore.Signal(int)

    @QtCore.Slot()
    def do_something(self):
        # Start long code here and update progress bar as needed in a still active UI.
        self.valueChanged.emit(0)
        print "doing something!"
        self.valueChanged.emit(100)

    @QtCore.Slot()
    def do_something_else(self):
        # Start long code here and update progress bar as needed in a still active UI.
        self.valueChanged.emit(0)
        print "doing something else!"
        self.valueChanged.emit(100)

    @QtCore.Slot()
    def and_so_fourth(self):
        # Start long code here and update progress bar as needed in a still active UI.
        self.valueChanged.emit(0)
        print "and so fourth, all in the new thread in a queue of which method was called first!"
        self.valueChanged.emit(100)

myTool = None

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

为什么我的 QThread 持续使 Maya 崩溃? 的相关文章

随机推荐

  • 在同一 SQL 查询中使用“WITH”和“UPDATE”语句

    我有一个表格 需要使用 Excel 电子表格中的一些数据进行更新 我正在考虑这样的查询 WITH temp AS SELECT abcd AS oldvalue defg AS newvalue FROM dual UNION SELECT
  • Fortran 90 - 尝试读取文件末尾之后的内容

    我在 Fortran 90 中遇到读取问题 我尝试读取 31488 行数据 我正在使用 Portland Group Fortran 90 编译器 我的错误信息是这样的 PGFIO F 217 列表定向读取 单元 14 尝试读取文件末尾 文
  • MacOS M1 上的 Docker kafka 配置时遇到问题

    我使用 macOS M1 Big Sur 11 2 3 但我的 kafka 无法正常运行 无法创建 列出主题 我不知道是不是操作系统的原因 但是kafka的日志只是这样 docker compose 日志 https i stack img
  • 使用 forEach() 返回数组值[重复]

    这个问题在这里已经有答案了 我希望返回存储在另一个对象中的数组的名称值 exports send function req res req body items forEach function item console log item
  • 设置服务总线辅助角色的 OperationTimeOut 属性

    我正在使用服务总线辅助角色模板创建辅助角色 我处理每条消息都要花费一分多钟的时间 因此 我发现工作角色多次收到相同的消息 大约每分钟收到一条消息 我认为这是因为该值默认为 60 秒 http msdn microsoft com en us
  • Android所有广播Intent列表在哪里

    我想接收Android广播消息 有所有意图的列表吗 我找到了广播意向列表 它可以位于sdks or android sdks platforms
  • 如何在 Tomcat 中为单个 Web 应用程序设置时区?

    在 Tomcat 中为单个 Web 应用程序设置时区的最佳方法是什么 我已经看到了更改 Tomcat 的命令行参数或环境变量的选项 但是有没有一种方法可以将其设置为独立于 WAR 文件而不依赖于任何 Tomcat 配置 编辑 再次强调 我正
  • Glassfish 4.1.1 - 使用我自己的证书的 DAS 抛出“j_security_check”错误

    我有一个 glassfish 4 1 1 实例正在运行 并将我自己的证书添加到我的应用程序中 直到那时一切都正常 但是 当我尝试访问 glassfish 管理员 DAS 时 连接不受信任 并且添加例外的按钮消失了 然后我发现了一些有趣的链接
  • 无法为 32 位 HKLM 设置注册表插入

    我想在 Inno setup 中创建一个带有子菜单项的上下文菜单 问题是 它在 64 位注册表 WoW6432Node 部分插入 HKLM 密钥 The 文档 http www jrsoftware org ishelp index php
  • 从变量打印mysql查询的结果

    所以我之前写过这个 在 php 中 但是每次我尝试 echo test 时 我只是返回资源 id 5 有谁知道如何从变量中实际打印出 mysql 查询 dave mysql query SELECT order date no of ite
  • Google Chrome 扩展浏览器和页面操作

    有没有办法在已经实现 browser action 的扩展中添加 page action 我想使用 browser action 显示带有书签列表的弹出窗口 同时使用 page action 为用户提供一种为当前页面添加书签并将其加载到列表
  • std::numeric_limits::infinity() 的倒数为零吗?

    C 标准 或 IEEE 754 浮点标准 中是否有任何内容可以保证1 std numeric limits
  • 在html中编码物理地址的最佳方法是什么?

    在 html 中编码物理地址的最佳方法是什么 以语义 可访问和 SEO 方式 Use a 微格式 vCard div class vcard span class fn Gregory Peck span a class org url h
  • 转到点击事件 jquery 上的锚链接

    正如描述所说 我在java脚本上发现了很多关于平滑滚动和位置属性的东西 但似乎没有什么能做我正在寻找的事情 这只是模仿html a 标签的功能 我不需要使用该项目的 html 链接标签 所以我得到的是你想向下滚动到一个元素而不使用 html
  • SECURITY_ERR:DOM 异常 18 仅在 Safari 中

    我有两台服务器 prod example com 和 img example com 所以在 prod 上 我使用画布处理 img 中的图像 在 FF 和 Chrome 中一切正常 但在 Safari 中我得到了这个SECURITY ERR
  • 如何向表格组件传递参数?

    我正在使用 Jaspersoft Studio 创建报告 发现将参数传递到表时出现问题 报告布局和结果 正如您在这些图片中看到的 当我尝试使用参数来设置表标题时 我得到了null 为了获取值 我在报表参数列表和表数据集参数列表中创建了相同的
  • 如何使用 jquery 调用 php 控制器方法?

    我正在开发一个 Web 应用程序 并且正在将 jquery 集成到其中 现在正在寻找使用 jquery 对我的控制器功能进行 ajax 调用 jquery ajax 我认为是有用的 但是如何调用我的控制器方法 ajax type POST
  • this.props.onChange() 的目的是什么?

    从反应快速入门 https facebook github io react docs lifting state up html https facebook github io react docs lifting state up h
  • 如何从浏览器控制台访问 GWT 的 JsInterop 导出类型?

    我正在运行 GWT 应用程序 并且想使用 JsInterop 快速测试某些内容 具体来说 我导出了一个enum package com mypackage test JsType enum MyEnum A B C 我想在编写任何代码之前检
  • 为什么我的 QThread 持续使 Maya 崩溃?

    我有一个 UI 我想在 Maya 内部使用线程 这样做的原因是这样我可以运行 Maya cmds 而无需挂起 冻结 UI 同时使用进度条等更新 UI 我已经阅读了 StackOverflow 中的一些示例 但我的代码每次运行时都会崩溃 我遵