PyQt中QDialog内绝对定位QWidget无法显示的问题排查
问题分析与解决
咱们先揪出代码里的两个关键问题,这俩就是导致绝对定位控件不显示的元凶:
1. 布局被重复分配给多个部件
你这段代码里犯了一个Qt布局的基础错误:同一个布局对象不能被设置给多个父部件。看这里:
widget.setLayout(layout) # ... dialog.setLayout(layout)
当你把layout第二次设置给dialog时,Qt会自动把这个布局从之前的widget上移除,绑定到dialog上。而且你后面根本没把widget加到dialog里,这个widget其实完全没起作用——不过这不是绝对控件不显示的直接原因,但也是代码里的冗余错误。
2. 绝对定位的控件没有适配内部布局的尺寸
你的absolute控件虽然加了布局和子控件,但它默认的尺寸是(0, 0),因为你没告诉它要根据内部布局的内容调整大小。Qt的控件如果用了布局,需要手动调用adjustSize()来让控件尺寸适配布局里的内容,不然它就保持最小尺寸,自然看不到。
修正后的代码
我把这两个问题都修复了,你可以直接运行试试:
import sys from PyQt5 import QtWidgets app = QtWidgets.QApplication(sys.argv) # 创建内容布局(直接把布局给dialog,去掉多余的widget) layout = QtWidgets.QVBoxLayout() for i in range(0, 10): layout.addWidget(QtWidgets.QLabel(f"line {i} - bla bla bla bla bla bla")) # 创建对话框并设置布局 dialog = QtWidgets.QDialog() dialog.setLayout(layout) # 创建绝对定位的控件 absolute_layout = QtWidgets.QVBoxLayout() absolute_layout.addWidget(QtWidgets.QLabel("Absolute positioned QWidget")) absolute_layout.addWidget(QtWidgets.QLabel("With some widgets in itself")) absolute_layout.addWidget(QtWidgets.QLabel("With some widgets in itself")) absolute_layout.addWidget(QtWidgets.QLabel("With some widgets in itself")) absolute = QtWidgets.QWidget(dialog) absolute.setLayout(absolute_layout) # 关键:让控件适配内部布局的大小 absolute.adjustSize() # 显示并移动位置 absolute.show() absolute.move(10, 10) absolute.raise_() dialog.show() sys.exit(app.exec_())
额外优化建议
如果你想做类似tooltip的效果,其实Qt有现成的方案,比如可以给绝对定位的控件设置Qt.ToolTip窗口标志,这样它会自带tooltip的行为(比如点击其他地方自动关闭):
absolute.setWindowFlags(QtCore.Qt.ToolTip)
这样体验会比纯绝对定位的控件更好哦。
内容的提问来源于stack exchange,提问作者miile7
相关产品推荐
相关产品推荐

