我在窗口的边缘创建了弹出窗口,我希望它在用户键入文本字段时展开弹出窗口。这当前有效,但窗口向右扩展。相反,我希望弹出窗口向左扩展(并保持右边缘固定到位)。
我最接近的例子就是下面的工作。在其中,我将获得每个文本输入的弹出窗口大小,然后根据其新大小移动弹出窗口。我觉得这应该有效,但事实并非如此。
在第一个文本输入上,弹出窗口跳转到屏幕的左边缘(仅限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()
答案 0 :(得分:1)
我已经修改了你在OP中提供的一些代码,并试图整理一个解决你的特定问题的例子。
我对代码所做的一些修改:
move_UI
; {/ li>的resizeEvent
内的Popup_Window
move_UI
中的方法Popup_Window
,以便弹出窗口不会闪烁到一个位置到另一个位置; eventFilter
; Popup_Window
Tool_Window
中的button.clicked.connect事件的函数。解决方案并不完美,当它在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_())
这导致:
我已经扩展了示例,现在弹出窗口以最小值100开始,当文本宽度超过此值时会延伸。此外,如果删除文本,弹出窗口的宽度将缩小,最小值为100。
这是通过计算QLineEdit
中内容更改时的文本宽度并使用该值为方法line_edit_text_changed
中的弹出窗口指定固定宽度来完成的。