Maya PySide:当我尝试将自定义信号连接到插槽时,Maya 崩溃

Posted

技术标签:

【中文标题】Maya PySide:当我尝试将自定义信号连接到插槽时,Maya 崩溃【英文标题】:Maya PySide: Maya crashes when I try to connect custom signal to slot 【发布时间】:2015-06-11 20:18:32 【问题描述】:

我使用 PySide 大约 2 周,我很喜欢它,但我无法理解一些更中间的概念。任何帮助将不胜感激。

我正在尝试使用 QLineEdit 和 QCompleter 在 PySide 中使用一些自定义 QEvent。我将旧样式用于信号/插槽连接,因为我还没有找到真正解释新语法的资源,但我认为这就是我的问题所在。

当我注释掉连接时,Maya 不会崩溃。一旦我重新打开它,每当我点击 Tab 时,Maya 就会崩溃。

任何帮助将不胜感激!

谢谢!

from PySide import QtCore, QtGui
from shiboken import wrapInstance 
import maya.OpenMayaUI as mui

def maya_main_window():
    ptr = mui.MQtUtil.mainWindow()
    return wrapInstance( long( ptr ), QtGui.QWidget )   

####################################################################
class MyWindow(QtGui.QDialog): 
    def __init__( self, parent=maya_main_window() ):
        super( MyWindow, self ).__init__( parent )

        # create objects
        self.la = QtGui.QLabel("Press tab in this box:")
        self.le = MyLineEdit()
        self.wordList = ["hi", "bye", "yes", "lane"]
        self.completer = QtGui.QCompleter( self.wordList, self )
        self.completer.setCompletionMode(QtGui.QCompleter.UnfilteredPopupCompletion)
        self.la2 = QtGui.QLabel("\nLook here:")
        self.le2 = QtGui.QLineEdit()
        self.le.setCompleter(self.completer)

        # layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.la)
        layout.addWidget(self.le)
        layout.addWidget(self.la2)
        layout.addWidget(self.le2)
        self.setLayout(layout)

        #####################
        # connections
        #####################
        self.connect(self.le, QtCore.SIGNAL("tabPressed"), self.on_tab)
        self.connect(self.le, QtCore.SIGNAL("escPressed"), self.on_esc)

        #####################
        # proper new style?
        #####################
        #self.le.tab_event.connect(self.on_tab)
        #self.le.esc_event.connect(self.on_tab)

    ######################
    # Slots
    ######################
    def on_tab(self):
        # I'd like tab to have the same function as arrow down
        print "tabbed"

    def on_esc(self):
        self.close()


####################################################################
class MyLineEdit( QtGui.QLineEdit):

    def __init__(self, parent=maya_main_window()):
        super( MyLineEdit, self ).__init__( parent  )

    ########################
    # Custom Signals
    ########################
    def tab_event(self, event):
        if (event.type()==QtCore.QEvent.KeyPress) and (event.key()==QtCore.Qt.Key_Tab):
            self.emit(QtCore.SIGNAL("tabPressed"))
            return True

        return QtGui.QLineEdit.event(self, event)

    def esc_event(self, event):
        if (event.type()==QtCore.QEvent.KeyPress) and (event.key()==QtCore.Qt.Key_Escape):
            self.emit(QtCore.SIGNAL("escPressed"))
            return True



####################################################################
if __name__ == "__main__": 
    # Development stuff
    try:
        myWindow_ui.close()
        myWindow_ui.deleteLater()
    except:
        pass


    myWindow_ui = MyWindow()
    myWindow_ui.show()


    # Development stuff
    try:
        myWindow_ui.show()
    except:
        myWindow_ui.close()
        myWindow_ui.deleteLater()

【问题讨论】:

这道题其实是4题。尝试将问题一次集中在一个问题上,以便回答者和网站用户可以从中受益。 在整篇文章中,您还没有提到 Maya 崩溃。您只是在标题中提到您收到错误,尽管您说 Maya 崩溃了。实际发生了什么?再次尝试将问题集中在一个问题上。 对不起,这是我的第一篇文章:/我昨晚实际上回答了我的问题,所以我会在一秒钟内发布答案。我将对我的原始帖子进行一些编辑,以便一切都相关。 太棒了!如果您能发布答案,那就太好了。 【参考方案1】:

我认为我的问题与我连接信号和插槽的方式有关。我发现这个很棒的 post 可以引导您了解新风格。

我在 MyLineEdit 的构造函数之前创建了一些变量。然后我在 tab_event 函数中使用了这些变量。然后我使用新的连接语法将信号连接到插槽。

这是使用 cmets 的更新代码:

from PySide import QtCore, QtGui
from shiboken import wrapInstance 
import maya.OpenMayaUI as mui

def maya_main_window():
    ptr = mui.MQtUtil.mainWindow()
    return wrapInstance( long( ptr ), QtGui.QWidget )   

####################################################################
class MyWindow(QtGui.QDialog): 
    def __init__( self, parent=maya_main_window() ):
        super( MyWindow, self ).__init__(  )

        # create objects
        self.la = QtGui.QLabel("Press tab in this box:")
        self.le = MyLineEdit()
        self.la2 = QtGui.QLabel("\nLook here:")
        self.le2 = QtGui.QLineEdit()

        # layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.la)
        layout.addWidget(self.le)
        layout.addWidget(self.la2)
        layout.addWidget(self.le2)
        self.setLayout(layout)

        # connections
        # Bad syntax
        #self.connect(self.le, QtCore.SIGNAL("tabPressed"), self.update)
        # Correct syntax
        self.le.tab_pressed.connect(self.update)

    # Slot   
    def update(self):
        newtext = str(self.le2.text()) + "tab pressed "
        self.le2.setText(newtext)

####################################################################
class MyLineEdit( QtGui.QLineEdit):

    # Create variables before the constructor
    tab_pressed = QtCore.Signal(str)
    signal_str = "tabPressed"

    def __init__(self, parent=None):
        super( MyLineEdit, self ).__init__(   )

    # Signal
    def event(self, event):

        # Variables inserted
        if (event.type()==QtCore.QEvent.KeyPress) and (event.key()==QtCore.Qt.Key_Tab):
            self.tab_pressed.emit(self.signal_str)
            return True

        return QtGui.QLineEdit.event(self, event)

####################################################################
if __name__ == "__main__": 
# Development stuff
    try:
        myWindow_ui.close()
        myWindow_ui.deleteLater()
    except:
        pass


    myWindow_ui = MyWindow()
    myWindow_ui.show()


    # Development stuff
    try:
        myWindow_ui.show()
    except:
        myWindow_ui.close()
        myWindow_ui.deleteLater()

【讨论】:

以上是关于Maya PySide:当我尝试将自定义信号连接到插槽时,Maya 崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Pyside2 信号槽 2d 数组签名定义,等效于列表列表

使用 PySide2 将 python 信号连接到 QML ui 插槽

(pyQt/pySide)setStyleSheet(border....) 使 QPushButton 在 Maya 中不可点击

Pyside (Qt) - 如何查询信号

maya 独立与 pyside2

Pyside uiLoader 捕获关闭事件信号