PyQt5中PlotWidget加入主窗口中央布局后其他控件消失的问题求助
问题:PyQt5中PlotWidget占据布局全部空间导致其他控件不可见
我正在用PyQt5构建一个可视化数据浏览器,需求是打开数据目录后自动绘制每个文件的图表,通过箭头切换文件生成对应图表。
在MainWindow的centralWidget中使用QVBoxLayout布局,单独添加测试用的彩色控件时显示正常,但加入PlotWidget后,所有彩色控件都被覆盖,仅显示图表。注释掉layout.addWidget(self.graphWidget)就能重新看到四个彩色控件。
我尝试给Color类添加sizeHint方法,也试过设置setMinimumWidth,但窗口放大后PlotWidget依然占满整个空间,问题没解决。
原始代码如下:
from PyQt5 import QtWidgets from pyqtgraph import PlotWidget, plot import pyqtgraph as pg from PyQt5.QtGui import QPalette, QColor import sys import os os.environ['QT_MAC_WANTS_LAYER'] = '1' # 测试用彩色控件 class Color(QtWidgets.QWidget): def __init__(self, color): super(Color, self).__init__() self.setAutoFillBackground(True) palette = self.palette() palette.setColor(QPalette.Window, QColor(color)) self.setPalette(palette) class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) central_widget = QtWidgets.QWidget() self.setCentralWidget(central_widget) # 创建图表控件 self.graphWidget = pg.PlotWidget() #self.setCentralWidget(self.graphWidget) # 图表样式设置 time = [1, 2, 3, 4, 5, 6, 7, 8, 9] counts = [1, 3, 7, 2, 9, 4, 10, 5, 12] self.graphWidget.setTitle("Plot title", color="k", size="18pt") self.graphWidget.setBackground('w') pen = pg.mkPen(color=(0, 102, 255), width=2) self.data_line = self.graphWidget.plot(time, counts, pen=pen) styles = {'color':'r', 'font-size':'18px'} self.graphWidget.setLabel('left', 'Counts', **styles) self.graphWidget.setLabel('bottom', 'Time (s)', **styles) pen = pg.mkPen(color=(0, 0, 0), width=2) self.graphWidget.plotItem.getAxis('left').setPen(pen) self.graphWidget.plotItem.getAxis('bottom').setPen(pen) self.graphWidget.plotItem.getAxis('right').setPen(pen) self.graphWidget.plotItem.getAxis('top').setPen(pen) self.graphWidget.getAxis('left').setTextPen('k') self.graphWidget.getAxis('bottom').setTextPen('k') layout = QtWidgets.QVBoxLayout(central_widget) layout.addWidget(self.graphWidget) layout.addWidget(Color('red')) layout.addWidget(Color('green')) layout.addWidget(Color('blue')) layout.addWidget(Color('red')) def main(): app = QtWidgets.QApplication(sys.argv) main = MainWindow() main.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
解决方案
问题根源是PlotWidget默认的尺寸策略(sizePolicy)为Expanding,会自动占据布局中所有可用空间,挤压其他控件。可以通过两种方式解决:
方法1:设置布局拉伸因子
在将控件添加到布局时,给PlotWidget设置合理的拉伸值,其他控件设置为0,让布局为所有控件分配空间:
修改布局添加控件的代码:
layout = QtWidgets.QVBoxLayout(central_widget) # 给PlotWidget设置拉伸因子1,其他控件拉伸因子0 layout.addWidget(self.graphWidget, stretch=1) layout.addWidget(Color('red'), stretch=0) layout.addWidget(Color('green'), stretch=0) layout.addWidget(Color('blue'), stretch=0) layout.addWidget(Color('red'), stretch=0)
方法2:调整PlotWidget的尺寸策略
限制PlotWidget的尺寸扩张行为,比如设置垂直尺寸策略为Preferred,让它优先使用自身建议尺寸,而非占满所有空间:
在创建graphWidget后添加以下代码:
# 创建图表控件 self.graphWidget = pg.PlotWidget() # 调整垂直尺寸策略 self.graphWidget.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred) # 可选:设置最大高度,进一步限制图表大小 self.graphWidget.setMaximumHeight(300)
修改后的完整代码(以方法1为例)
from PyQt5 import QtWidgets from pyqtgraph import PlotWidget, plot import pyqtgraph as pg from PyQt5.QtGui import QPalette, QColor import sys import os os.environ['QT_MAC_WANTS_LAYER'] = '1' # 测试用彩色控件 class Color(QtWidgets.QWidget): def __init__(self, color): super(Color, self).__init__() self.setAutoFillBackground(True) palette = self.palette() palette.setColor(QPalette.Window, QColor(color)) self.setPalette(palette) class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) central_widget = QtWidgets.QWidget() self.setCentralWidget(central_widget) # 创建图表控件 self.graphWidget = pg.PlotWidget() #self.setCentralWidget(self.graphWidget) # 图表样式设置 time = [1, 2, 3, 4, 5, 6, 7, 8, 9] counts = [1, 3, 7, 2, 9, 4, 10, 5, 12] self.graphWidget.setTitle("Plot title", color="k", size="18pt") self.graphWidget.setBackground('w') pen = pg.mkPen(color=(0, 102, 255), width=2) self.data_line = self.graphWidget.plot(time, counts, pen=pen) styles = {'color':'r', 'font-size':'18px'} self.graphWidget.setLabel('left', 'Counts', **styles) self.graphWidget.setLabel('bottom', 'Time (s)', **styles) pen = pg.mkPen(color=(0, 0, 0), width=2) self.graphWidget.plotItem.getAxis('left').setPen(pen) self.graphWidget.plotItem.getAxis('bottom').setPen(pen) self.graphWidget.plotItem.getAxis('right').setPen(pen) self.graphWidget.plotItem.getAxis('top').setPen(pen) self.graphWidget.getAxis('left').setTextPen('k') self.graphWidget.getAxis('bottom').setTextPen('k') layout = QtWidgets.QVBoxLayout(central_widget) # 设置拉伸因子 layout.addWidget(self.graphWidget, stretch=1) layout.addWidget(Color('red'), stretch=0) layout.addWidget(Color('green'), stretch=0) layout.addWidget(Color('blue'), stretch=0) layout.addWidget(Color('red'), stretch=0) def main(): app = QtWidgets.QApplication(sys.argv) main = MainWindow() main.show() sys.exit(app.exec_()) if __name__ == '__main__': main()
这样修改后,PlotWidget和彩色控件会同时显示在垂直布局中,窗口放大时PlotWidget会按比例扩展,其他控件保持原有大小。
内容的提问来源于stack exchange,提问作者clairecc
相关产品推荐
相关产品推荐

