0

I'd like to create a popup at the position of a clicked button and also offset that popup along the left edge of the existing window.

Right now I'm getting the position of the button fine, but it seems that the position of the window is off a little because when the popup is created it's about 200 pixels off to the left. I've commented the relevant sections below in my code. Thanks for any help/critiques.

from PySide import QtCore, QtGui
from shiboken import wrapInstance 

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

############################################
class Tool_Window(QtGui.QDialog):
    def __init__(self, parent = get_parent() ):
        super(Tool_Window, 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.button1 = QtGui.QPushButton()
        self.button1.setMaximumWidth(50)
        self.button2 = QtGui.QPushButton()
        self.button2.setMaximumWidth(50)
        self.button3 = QtGui.QPushButton()
        self.button3.setMaximumWidth(50)

    #-------------------------------------------
    def create_layout(self):
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        layout.addWidget(self.button3)
        layout.addStretch()
        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.button1.clicked.connect( self.on_left_click1 )
        self.button2.clicked.connect( self.on_left_click2 )
        self.button3.clicked.connect( self.on_left_click3 )

        # 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_click1(self):
        self.popup = Popup_Window(self, self.button1 )                    # Passing button in so I can get it's position
        self.popup.show()

    def on_left_click2(self):
        self.popup = Popup_Window(self, self.button2 )      
        self.popup.show()

    def on_left_click3(self):
        self.popup = Popup_Window(self, self.button3 )      
        self.popup.show()

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

        self.button_pos = button                                           # Creating variable for the button
        self.toolWindow= mainUIWindow
        self.setAttribute( QtCore.Qt.WA_DeleteOnClose )
        #self.setMinimumWidth(100)                                         # I need a minimum width

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

    #-------------------------------------------
    def move_UI( self ):                                                    # Move popup based on pos of window and buttons
        ''' Moves the UI to the cursor's position '''
        self.setWindowFlags(QtCore.Qt.Popup)                               
        self.line_edit.setFocus()

        # Get button position                                          
        btn_global_point = self.button_pos.mapToGlobal(self.button_pos.rect().topLeft())  

        # Get window position  
        win_global_point = self.mapToGlobal(self.rect().topLeft()) 

        self.move(btn_global_point - win_global_point)                      # Here is where I find the distance between the window edge and button edge 


    #-------------------------------------------
    def create_gui( self ):
        ''' Visible GUI stuff '''
        self.my_label = QtGui.QLabel("default text")
        self.line_edit = QtGui.QLineEdit()
        self.line_edit.setMaxLength( 30 )
        self.push_btn = QtGui.QPushButton( "Hey" )
        self.push_btn.setMaximumWidth( 30 )

    #-------------------------------------------
    def create_layout( self ):
        self.button_layout = QtGui.QVBoxLayout()
        self.button_layout.addWidget( self.my_label )
        self.button_layout.addWidget( self.line_edit )
        self.button_layout.addWidget( self.push_btn )
        self.setLayout(self.button_layout)

    #-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#
    def create_connections( self ):
        self.line_edit.textChanged.connect( self.on_text_changed )

    #-----#-----#-----#-----#-----#-----#-----#-----#-----#
    def on_text_changed( self ):
        typed_name = self.line_edit.text()
        self.my_label.setText(typed_name)


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

    test_ui = Tool_Window()
    test_ui.show()

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

Solution:

# Get button position                                          
btn_global_point = self.button_pos.mapToGlobal(self.button_pos.rect().topLeft())  

# Get window position  
win_global_point = self.toolWindow.mapToGlobal(self.rect().topLeft()) 

self.move(win_global_point.x(), btn_global_point.y())
Mike Bourbeau
  • 481
  • 11
  • 29

1 Answers1

1

If I understand what you want to achieve, you have to keep only the y-value of button position and the x-value of window position.

So try this code:

    # Get y button position                                          
    btn_global_point_y = self.button_pos.mapToGlobal(self.button_pos.rect().topLeft()).y()  

    # Get window position  
    win_global_point_x = self.mapToGlobal(self.rect().topLeft()).x() 

    self.move(win_global_point_x, btn_global_point_y)   

With this lines you move the popup window at the height of the button and snap it to the left edge of the window.

Ale_32
  • 648
  • 1
  • 6
  • 16
  • Thanks for the reply! This is giving me the correct y-coords, but the x-coords are still off. The code is creating the popup window along the left edge of my main monitor (I have a 2 monitor setup) regardless of my main application window's size. In the program that I'm creating this tool for, there is a main application window that I create the Tool_Window in, then I'd like to create a Popup_Window that is attached to that Tool_Window's left edge. Any thoughts? – Mike Bourbeau Jul 25 '15 at 13:26
  • 1
    Change self.rect().topLeft() with self.toolWindow.rect().topLeft(), where toolWindow is your pyqt object that you want – Ale_32 Jul 25 '15 at 13:53
  • Got it! Thanks again – Mike Bourbeau Jul 25 '15 at 14:08