QWidget 实现 打破布局 或者 当前窗体内的 弹窗 (借助伪造实现)
but = QtWidgets.QToolButton(Dialog2) but.setText('**') but.setAutoRaise(True) layout.addWidget(but) Dialog2.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.Tool) Dialog2.setWindowOpacity(1) Dialog2.setAttribute(QtCore.Qt.WA_TranslucentBackground)
Qt.Popup Window Indicates that the widget is a pop-up top-level window, i.e. that it is modal, but has a window system frame appropriate for pop-up menus.
Qt.Tool Indicates that the widget is a tool window. A tool window is often a small window with a smaller than usual title bar and decoration, typically used for collections of tool buttons. If there is a parent, the tool window will always be kept on top of it. If there isn't a parent, you may consider using Qt::WindowStaysOnTopHint as well. If the window system supports it, a tool window can be decorated with a somewhat lighter frame. It can also be combined with Qt::FramelessWindowHint. On OS X, tool windows correspond to the Floating class of windows. This means that the window lives on a level above normal windows; it impossible to put a normal window on top of it. By default, tool windows will disappear when the application is inactive. This can be controlled by the Qt::WA_MacAlwaysShowToolWindow attribute.
from PyQt5 import QtCore, QtGui, QtWidgets class Popup(QtWidgets.QWidget): def __init__(self, parent=None): super(Popup, self).__init__(parent ) self.setWindowOpacity(1) # 必须是以顶级弹窗的形式出现,否则最小的长度不好设置 # 最大化 和 最小化的按钮占地方 self.setWindowFlags( QtCore.Qt.Popup | QtCore.Qt.FramelessWindowHint ) self.setAttribute(QtCore.Qt.WA_TranslucentBackground) self.setupUi() # 只能放两个 self._uis = [] def setupUi(self): layout_main = QtWidgets.QVBoxLayout(self) self.setLayout(layout_main) layout_main.setContentsMargins(0, 0, 0, 0) layout_main.setSpacing(0) layout_top = QtWidgets.QHBoxLayout() layout_top_1 = QtWidgets.QHBoxLayout() spacerItem_1 = QtWidgets.QSpacerItem(2, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) self._layout_top = layout_top_1 layout_top.addLayout(layout_top_1) layout_top.addItem(spacerItem_1) layout_top.setStretch(1, 1) layout_bottom = QtWidgets.QHBoxLayout() layout_bottom_1 = QtWidgets.QHBoxLayout() self._layout_bottom = layout_bottom_1 spacerItem_2 = QtWidgets.QSpacerItem(2, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) layout_bottom.addLayout(layout_bottom_1) layout_bottom.addItem(spacerItem_2) layout_bottom.setStretch(1, 1) layout_main.addLayout(layout_top) layout_main.addLayout(layout_bottom) # 隐藏事件 的 重新 def hideEvent(self, event): print('hideEvent') def addShow(self, ui_1, ui_2): self._layout_top.addWidget(ui_1) self._layout_bottom.addWidget(ui_2) self._uis = [ui_1, ui_1] def showPop(newText): sender = widget.sender() print('newText', newText, sender.text(), pop.width()) # 需计算长度才行 pop.resize(80, 80) pop.show() but_1.setFocus() point = input.pos() point_global = input.mapToGlobal(point) pop.move(point_global.x() - point.x(), point_global.y() - point.y()) print(point_global.x(), point_global.y(), point.x(), point.y()) if __name__ == "__main__": import sys app = QtWidgets.QApplication(sys.argv) pop = Popup() but_1 = QtWidgets.QLineEdit() but_1.setFixedSize(50, 20) but_1.setText('aa') but_2 = QtWidgets.QLineEdit() but_2.setFixedSize(80, 80) but_2.setText('bb') pop.addShow(but_1, but_2) print('aa') widget = QtWidgets.QWidget() layout = QtWidgets.QVBoxLayout(widget) input = QtWidgets.QLineEdit() layout.addWidget(input) input2 = QtWidgets.QLineEdit() layout.addWidget(input2) input.textChanged.connect(showPop) widget.show() sys.exit(app.exec_())