PySide:根据现有UI元素的位置在某个位置创建窗口

时间:2015-07-24 15:12:46

标签: popup position pyside maya

我在Maya中创建了一个具有弹出窗口的工具。我希望弹出窗口会根据您点击的UI元素显示在设定的位置。

当我运行脚本时,工具出现在我的光标位置(这很好)。然后,当您单击该按钮时,会弹出另一个窗口(这不起作用)。

问题是弹出窗口出现在屏幕的左上方,而不是出现在QPushButton的位置。我想如果我在我的Popup_Window类的move_ui方法中用self.button_popup.pos()替换QtGui.QCursor.pos()它会起作用......但它没有。

有什么想法?这是我到目前为止在右边评论的关键区域:

from PySide import QtCore, QtGui
from shiboken import wrapInstance 

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

############################################
class RightClickMenuButton(QtGui.QDialog):
    def __init__(self, parent = get_parent() ):
        super(RightClickMenuButton, self).__init__(parent)

        self.setContextMenuPolicy(QtCore.Qt.ActionsContextMenu)

        # Commands
        self.move_UI()
        self.create_gui()
        self.create_layout()
        self.create_connections()

    #-------------------------------------------
    def create_gui(self):
        self.button = QtGui.QPushButton()

    #-------------------------------------------
    def create_layout(self):
        layout = QtGui.QHBoxLayout()
        layout.addWidget(self.button)
        self.setLayout(layout)

    #-------------------------------------------
    def move_UI( self ):
        ''' Moves the UI to the cursor's position '''
        pos = QtGui.QCursor.pos()
        self.move(pos.x()+20, pos.y()+15)

    #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-
    def create_connections(self):
        # Left click
        self.button.clicked.connect( self.on_left_click )

        # Right click delete
        delete = QtGui.QAction(self)
        delete.setText("remove")
        delete.triggered.connect(self.remove_button)
        self.addAction(delete)

    #-----#-----#-----#-----#-----#-----#-----#-----#-----#-
    def remove_button(self):
        self.deleteLater()

    def on_left_click(self):
        self.popup = Popup_Window(self, self.button )      # Passing button in so I can get it's position
        self.popup.show()

############################################
class Popup_Window( QtGui.QDialog ):
    def __init__( self, mainUIWindow, button ):
        super( Popup_Window, self ).__init__()

        self.button_pos = button                           # Creating variable 
        self.mainUIWindow = mainUIWindow
        self.setAttribute( QtCore.Qt.WA_DeleteOnClose )

        # Commands
        self.move_UI()
        self.create_gui()
        self.create_layout()

    #-------------------------------------------
    def move_UI( self ):
        ''' Moves the UI to the cursor's position '''
        pos = self.button_pos.pos()                        # Using the button's position to determine window position
        self.move(pos.x()+20, pos.y()+15)

    #-------------------------------------------
    def create_gui( self ):
        ''' Visible GUI stuff '''
        self.push_btn = QtGui.QPushButton( "Create" )

    #-------------------------------------------
    def create_layout( self ):
        self.label = QtGui.QLabel( "Hey" )
        self.button_layout = QtGui.QHBoxLayout()
        self.button_layout.addWidget( self.push_btn )

############################################
if __name__ == '__main__':
    # Things to fix PySide Maya bug
    try:
        test_ui.close()
        test_ui.deleteLater()
    except:
        pass

    test_ui = RightClickMenuButton()
    test_ui.show()

    try:
        test_ui.show()
    except:
        test_ui.close()
        test_ui.deleteLater() 

1 个答案:

答案 0 :(得分:1)

问题在于widget.pos()为您提供了小部件(相对于窗口)的相对位置,该位置非常小,接近(0,0),即窗口空间的左上角。

如果你想要小部件的全局屏幕位置,你必须写:

rel_pos = widget.pos()
pos = widget.mapToGlobal(rel_pos)

所以 Popup_Window 类中的 move_UI 函数变为:

def move_UI( self ):
        ''' Moves the UI to the widget position '''
        rel_pos = self.button_pos.pos()                        # Using the button's position to determine window position
        pos = self.button_pos.mapToGlobal(rel_pos)
        self.move(pos.x()+20, pos.y()+15)