他一直困扰着我,主要是因为移动小部件和诸如此类的方法有多少组合。基本上我有一个简单的小部件,我希望能够在我的应用程序的特定区域弹出。问题是我似乎无法让它弹出我想要的地方。另外,我想以一种方式设置它,我可以根据它是否弹出指向应用程序左上角的小部件来调整它的“指针”一侧,而不是指向底部 - 右。
理想情况下,我可以将弹出窗口放置在父窗口小部件的边缘附近,并根据它的位置进行锚定。这是我一直在尝试的。
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class popup(QWidget):
def __init__(self, parent = None, widget=None):
QWidget.__init__(self, parent)
layout = QGridLayout(self)
button = QPushButton("Very Interesting Text Popup. Here's an arrow ^")
layout.addWidget(button)
self.move(widget.rect().bottomLeft())
class Window(QWidget):
def __init__(self):
QWidget.__init__(self)
self.button = QPushButton('Hit this button to show a popup', self)
self.button.clicked.connect(self.handleOpenDialog)
self.button.move(250, 50)
self.resize(600, 200)
def handleOpenDialog(self):
self.popup = popup(self, self.button)
self.popup.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec_())
此代码生成一个随机位于窗口小部件中间的按钮。我想要得到的是,在这个例子中,弹出窗口显示在右下方,其“pivot”位于右上角,弹出按钮中的箭头指向窗口小部件的右下角。然而,它正在窗口的左上角突然出现。在我用.move,.setGeometry和使用QRect玩弄的所有内容中,我不能为我的生活弄清楚这一点。对谁能伸出援助之手的巨大荣誉。谢谢!
答案 0 :(得分:1)
我知道这是旧的,但我最近在寻找这个,这是最好的答案;我有一个有用的补充(对于其他任何人寻找这个食谱!)
我将它实现为mixin,我认为它为您的对话提供了更大的灵活性:
class PopupDialogMixin(object): # will not work (with PySide at least) unless implemented as 'new style' class. I.e inherit from object
def makePopup(callWidget):
"""
Turns the dialog into a popup dialog.
callWidget is the widget responsible for calling the dialog (e.g. a toolbar button)
"""
self.setContentsMargins(0,0,0,0)
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Popup)
self.setObjectName('ImportDialog')
# Move the dialog to the widget that called it
point = callWidget.rect().bottomRight()
global_point = callWidget.mapToGlobal(point)
self.move(global_point - QtCore.QPoint(self.width(), 0))
然后,您的自定义对话框将继承QtCore.QDialog
和PopupDialogMixin
。这使您可以选择以“正常”方式使用对话框或使其成为弹出对话框。 e.g:
dlg = MyDialog(self)
dlg.makePopup(self.myButton)
我认为将其作为mixin实现会带来许多好处:
__init__
之外,无需向parent
传递任何额外内容。 答案 1 :(得分:0)
这里你去 - 评论有点解释它背后的逻辑 - 因为问题是一个例子和定位,我保持其余的代码相同,除了弹出类,但只是提到它的宠物peeve - 你不应该导入*(永远),尤其是像PyQt4.QtCore / QtGui那样大的东西......
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
class popup(QWidget):
def __init__(self, parent = None, widget=None):
QWidget.__init__(self, parent)
layout = QGridLayout(self)
button = QPushButton("Very Interesting Text Popup. Here's an arrow ^")
layout.addWidget(button)
# adjust the margins or you will get an invisible, unintended border
layout.setContentsMargins(0, 0, 0, 0)
# need to set the layout
self.setLayout(layout)
self.adjustSize()
# tag this widget as a popup
self.setWindowFlags(Qt.Popup)
# calculate the botoom right point from the parents rectangle
point = widget.rect().bottomRight()
# map that point as a global position
global_point = widget.mapToGlobal(point)
# by default, a widget will be placed from its top-left corner, so
# we need to move it to the left based on the widgets width
self.move(global_point - QPoint(self.width(), 0))
class Window(QWidget):
def __init__(self):
QWidget.__init__(self)
self.button = QPushButton('Hit this button to show a popup', self)
self.button.clicked.connect(self.handleOpenDialog)
self.button.move(250, 50)
self.resize(600, 200)
def handleOpenDialog(self):
self.popup = popup(self, self.button)
self.popup.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
win.show()
sys.exit(app.exec_())