Popup PySide:更改窗口的大小/增长方向

Popup PySide:更改窗口的大小/增长方向,popup,resize,pyside,direction,Popup,Resize,Pyside,Direction,我在窗口边缘创建了一个弹出窗口,我希望它在用户输入文本字段时扩展弹出窗口。这目前可以工作,但窗口正在向右扩展。相反,我希望弹出窗口向左扩展(并将右边缘固定在适当的位置) 下面是我最接近的工作示例。在它里面,我得到了每个文本输入的弹出窗口的大小,然后根据它的新大小移动弹出窗口。我觉得这应该行得通,但不行 在第一次输入文本时,弹出窗口跳到我的屏幕的左边缘(仅x变换)。在第二次文本输入时,弹出窗口跳回其原始位置。在第三个文本输入时,弹出窗口跳回屏幕的左边缘。在第四个输入上。。。你明白了。我还想提到的是

我在窗口边缘创建了一个弹出窗口,我希望它在用户输入文本字段时扩展弹出窗口。这目前可以工作,但窗口正在向右扩展。相反,我希望弹出窗口向左扩展(并将右边缘固定在适当的位置)

下面是我最接近的工作示例。在它里面,我得到了每个文本输入的弹出窗口的大小,然后根据它的新大小移动弹出窗口。我觉得这应该行得通,但不行

在第一次输入文本时,弹出窗口跳到我的屏幕的左边缘(仅x变换)。在第二次文本输入时,弹出窗口跳回其原始位置。在第三个文本输入时,弹出窗口跳回屏幕的左边缘。在第四个输入上。。。你明白了。我还想提到的是,窗口的整体增长看起来是从弹出窗口的中心开始的,而不是从右边缘开始的

我注意到,在点击按钮后,它会一直高亮显示,直到我的鼠标经过它。这会导致这个问题吗

任何想法或更好的方式来实现这一效果将是伟大的,谢谢

from PySide import QtCore, QtGui
import maya.OpenMayaUI as mui
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)

        # 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)
        blank_layout = QtGui.QVBoxLayout()
        main_layout = QtGui.QHBoxLayout( self )
        main_layout.addLayout(blank_layout)
        main_layout.addLayout(layout)
        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.__popup_filter = ClosePopupFilter()
        self.installEventFilter(self.__popup_filter) 
        self.setWindowFlags(QtCore.Qt.Popup)
        '''
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint |
                            QtCore.Qt.WindowStaysOnTopHint |
                            QtCore.Qt.CustomizeWindowHint |
                            QtCore.Qt.Tool)    
        '''
        self.button_pos = button       
        self.toolWindow = toolWindow                                        
        self.setAttribute( QtCore.Qt.WA_DeleteOnClose )
        self.resize(100, 100) 

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

    #-------------------------------------------
    def move_UI( self ):                                                        # Method that I use to place the popup window initially  
        self.line_edit.setFocus() 
        # Get button position                                          
        self.btn_global_point = self.button_pos.mapToGlobal(self.button_pos.rect().topLeft())  
        print self.btn_global_point
        # Get window position  
        self.win_global_point = self.toolWindow.mapToGlobal(self.rect().topLeft()) 
        print self.win_global_point
        # Get popup Size
        self.popup_size = self.mapToGlobal(self.rect().topRight())
        print self.popup_size
        # Move the window
        self.move((self.win_global_point.x()-self.popup_size.x()), self.btn_global_point.y())

    #-------------------------------------------
    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.button_layout.setContentsMargins(0, 0, 0, 0)
        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) 
        self.move_UI()                                                          # I reuse the move method to move the ui on text edit

############################################
class  ClosePopupFilter(QtCore.QObject):
    ''' Close popup window '''
    def  eventFilter(self, target, event):
        if event.type() == QtCore.QEvent.WindowDeactivate:
            target.close()
        return  False



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()

我已经对您在OP中提供的代码进行了一点修改,并尝试结合一个示例来解决您的特定问题

我对代码所做的一些修改:

  • 弹出窗口的
    resizeEvent
    内触发
    移动UI
  • 修正了
    弹出窗口
    中的
    移动UI
    方法,使弹出窗口不会从一个位置闪烁到另一个位置
  • 直接在
    弹出窗口中移动
    事件过滤器
  • 合并了处理按钮事件的函数。在
    Tool\u窗口中单击。连接
解决方案并不完美,当弹出窗口在Ubuntu中扩展和移动时,仍然会有一些“闪烁”。然而,这在Windows7中不是很明显。如果我想到另一个解决方案,我会做一个更新

from PySide import QtCore, QtGui
import sys

class Tool_Window(QtGui.QDialog): #=============================================
    def __init__(self, parent=None): 
        super(Tool_Window, self).__init__(parent)

        self.create_gui()
        self.create_layout()
        self.create_connections()

    def create_gui(self): #=====================================================

        self.button1 = QtGui.QPushButton('Button 1')
        self.button2 = QtGui.QPushButton('Button 2')
        self.button3 = QtGui.QPushButton('Button 3')

    def create_layout(self): #==================================================

        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.button1)
        layout.addWidget(self.button2)
        layout.addWidget(self.button3)
        self.setLayout(layout)

    def create_connections(self): #=============================================

        self.button1.clicked.connect(self.on_lef_click )
        self.button2.clicked.connect(self.on_lef_click )
        self.button3.clicked.connect(self.on_lef_click )

    def on_lef_click(self): #===================================================

        button = self.sender()

        self.popup = Popup_Window(self, button)
        self.popup.show()


class Popup_Window( QtGui.QWidget ): #==========================================
    def __init__( self, parent, button):
        super(Popup_Window, self ).__init__(parent)

        self.setWindowFlags(QtCore.Qt.Popup)

        self.button = button       
        self.parent = parent

        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        #---- set layout key dimension ----

        self.min_width = 100
        self.frame_thick = 10
        self.setFixedWidth(self.min_width)

        #---- init GUI ----

        self.installEventFilter(self)

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

        self.line_edit.setFocus()


    def create_gui( self ): #===================================================

        self.my_label = QtGui.QLabel("default text")
        self.my_label.setAlignment(QtCore.Qt.AlignRight)
        self.line_edit = QtGui.QLineEdit()
        self.line_edit.setAlignment(QtCore.Qt.AlignRight)
        self.line_edit.setMaxLength( 50 )


    def create_layout( self ): #================================================

        button_layout = QtGui.QGridLayout()

        button_layout.addWidget(self.my_label, 0, 0)
        button_layout.addWidget(self.line_edit, 1, 0)

        button_layout.setContentsMargins(self.frame_thick, self.frame_thick,
                                         self.frame_thick, self.frame_thick)

        self.setLayout(button_layout)


    def create_connections(self): #=============================================
        self.line_edit.textChanged.connect(self.line_edit_text_changed)


    def line_edit_text_changed(self, text):  #==================================

        #---- set the text in label ----

        self.my_label.setText(text)

        #---- determine new width of popup ----

        fm = self.line_edit.fontMetrics()
        txtWidth = fm.boundingRect(text).width() + 10 # Padding to the left.
                                                      # Value is arbitrary.

        newWidth = max(txtWidth + self.frame_thick * 2, self.min_width)

        self.setFixedWidth(newWidth)


    def eventFilter(self, source, event): #=====================================

        if event.type() == QtCore.QEvent.WindowDeactivate:
            self.close()

        return QtGui.QWidget.eventFilter(self, source, event)

    def resizeEvent(self, event): #=============================================

        self.move_UI()        
        QtGui.QWidget.resizeEvent(self, event)


    def move_UI(self): # =======================================================

        y_btn = self.button.mapToGlobal(QtCore.QPoint(0, 0)).y()        
        x_win = self.parent.mapToGlobal(QtCore.QPoint(0, 0)).x()

        w_pop = self.frameGeometry().width()

        x = x_win - w_pop - 12 # 12 is an arbitrary value.
        y = y_btn

        self.move(QtCore.QPoint(x, y))


if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    instance_1 = Tool_Window()
    instance_1.show()
    sys.exit(app.exec_())
这导致:

更新(2015-07-30):弹出窗口缩小到内容的宽度 我已经扩展了这个示例,现在弹出窗口的最小值为100,当文本宽度超过这个值时,这个值会扩展。此外,如果删除文本,弹出窗口的宽度将缩小到最小值100


这是通过在内容更改时计算
QLineEdit
中文本的宽度,并使用该值为方法
line\u edit\u text\u changed
中的弹出窗口指定一个固定宽度来完成的。这真是个好答案!非常感谢您抽出时间做这件事this@MikeBourbeau谢谢你竖起大拇指。如果您感兴趣,我很好奇如何将弹出窗口缩小到
QLineEdit
的内容。我已经在示例中添加了这样做的代码。不过,我还没有对它进行全面测试。