PySide:根据按钮的位置和 window 的边缘创建弹出窗口
PySide: Create popup based on location of button and window's edge
我想在单击按钮的位置创建一个弹出窗口,并沿现有 window.
的左边缘偏移该弹出窗口
现在我可以很好地确定按钮的位置,但 window 的位置似乎有点偏离,因为在创建弹出窗口时它向左偏移了大约 200 像素。我在我的代码中评论了下面的相关部分。感谢任何 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()
解法:
# 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())
如果我明白你想要达到什么目的,你只需要保留按钮位置的 y 值 和 x 值 的 window 个位置。
所以试试这个代码:
# 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)
使用此行,您可以将弹出窗口 window 移动到按钮的高度并将其对齐到 window 的左边缘。
我想在单击按钮的位置创建一个弹出窗口,并沿现有 window.
的左边缘偏移该弹出窗口现在我可以很好地确定按钮的位置,但 window 的位置似乎有点偏离,因为在创建弹出窗口时它向左偏移了大约 200 像素。我在我的代码中评论了下面的相关部分。感谢任何 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()
解法:
# 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())
如果我明白你想要达到什么目的,你只需要保留按钮位置的 y 值 和 x 值 的 window 个位置。
所以试试这个代码:
# 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)
使用此行,您可以将弹出窗口 window 移动到按钮的高度并将其对齐到 window 的左边缘。