如何将QPushButton锚定到QScrollArea内的地图特定位置并随其滚动?
嘿,你遇到的问题根源很明确:你把按钮直接作为QScrollArea的子控件了,而不是把它放在承载地图的QLabel里面。QScrollArea只会滚动它通过setWidget()设置的那个核心控件(也就是你的self.label),所以只有这个控件的子元素才会跟着滚动。
下面是修改后的完整代码,我标注了关键改动点:
import sys from PyQt5.QtGui import QPixmap, QPalette from PyQt5.QtWidgets import QApplication, QScrollArea, QLabel, QPushButton class MapGUI(QScrollArea): def __init__(self): super().__init__() self.initUI() def initUI(self): screen_resolution = app.desktop().screenGeometry() width, height = screen_resolution.width(), screen_resolution.height() self.setGeometry(0, 0, height, height) self.setWindowTitle("The World") self.label = QLabel() self.pixmap_unscaled = QPixmap("The_World.png") # Scaling the image to half the size self.pixmap = self.pixmap_unscaled.scaled(int(self.pixmap_unscaled.width() * 0.5), int(self.pixmap_unscaled.height() * 0.5)) self.label.setPixmap(self.pixmap) # 可选:如果希望图片随滚动区域缩放适配,可开启此设置(按需选择) # self.label.setScaledContents(True) # 关键改动1:将按钮的父控件从self(QScrollArea实例)改为self.label(地图承载标签) self.button = QPushButton('PyQt5 button', self.label) self.button.setToolTip('This is an example button') # 关键改动2:现在的坐标是相对于地图标签的局部位置,而非滚动窗口全局坐标 self.button.setGeometry(100, 100, 100, 50) self.setBackgroundRole(QPalette.Dark) self.setWidget(self.label) self.show() if __name__ == "__main__": app = QApplication(sys.argv) map_gui = MapGUI() # 避免用map作为变量名,它是Python内置函数 sys.exit(app.exec_())
核心修改说明:
- 控件层级调整:把按钮的父对象改为
self.label后,按钮就成为地图标签的子控件,会完全跟随标签在滚动区域内的移动。 - 坐标参考系更新:按钮的
setGeometry()现在基于地图标签的局部坐标,你可以根据实际地图上国家的位置调整数值,让按钮精准对应目标区域。 - 小细节优化:将变量名
map改为map_gui,避免覆盖Python内置的map()函数,这是编写Python代码的好习惯。
这样修改后,滚动地图时按钮就会跟着一起移动啦!
内容的提问来源于stack exchange,提问作者Christopher Berry
相关产品推荐
相关产品推荐

