Matplotlib在PyQt4的应用,matplotlibpyqt4

来源:http://www.sh-fengwen.com 作者:鲜果干果 人气:174 发布时间:2019-09-03
摘要:Matplotlib在PyQt4的应用,matplotlibpyqt4 Matplotlib作为Python中著名的数据可视化工具,其官网也提供了在PyQt4中使用的源码,这里举一个应用实例,以备不时之需。 1) 利用Qt Designer创建GUI界面

Matplotlib在PyQt4的应用,matplotlibpyqt4

Matplotlib作为Python中著名的数据可视化工具,其官网也提供了在PyQt4中使用的源码,这里举一个应用实例,以备不时之需。

1) 利用Qt Designer创建GUI界面

Demo的GUI界面,如图1所示,其中利用QFrame作为放置Matplotlib界面的容器。然后调用pyuic4.bat -o ui_maindialog.py maindialog.ui编译UI界面。

图1 GUI设计界面

2) maindialog.py程序代码

#!/usr/bin/env python
#-*- coding: utf-8 -*-

import numpy as np
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from ui_maindialog import Ui_MainDialog
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas # Matplotlib对PyQt4的支持
from matplotlib.figure import Figure

class MainDialog(QDialog, Ui_MainDialog):
    def __init__(self, parent=None):
        super(MainDialog, self).__init__(parent)
        self.setupUi(self)
        self._createFigures()
        self._createLayouts()

  # 创建Matplotlib的画布
    def _createFigures(self):
        self._fig = Figure(figsize=(8, 6), dpi=100, tight_layout=True) 
        self._fig.set_facecolor("#F5F5F5") # 背景色
        self._fig.subplots_adjust(left=0.08, top=0.92, right=0.95, bottom=0.1) # 四周Margin
        self._canvas = FigureCanvas(self._fig) # 画布
        self._ax = self._fig.add_subplot(111) # 增加subplot
        self._ax.hold(True)
        self._initializeFigure()

    def _createLayouts(self):
        layout = QHBoxLayout(self.frame)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self._canvas) # Add Matplotli

    def _initializeFigure(self):
        Font = {'family': 'Tahoma',
                'weight': 'bold',
                'size': 10}
        # Abscissa
        self._ax.set_xlim([380, 780])
        self._ax.set_xticks([380, 460, 540, 620, 700, 780])
        self._ax.set_xticklabels([380, 460, 540, 620, 700, 780], fontdict=Font)
        self._ax.set_xlabel("Wavelength (nm)", fontdict=Font)
        # Ordinate
        self._ax.set_ylim([0.0, 1.0])
        self._ax.set_yticks(np.arange(0.0, 1.1, 0.2))
        self._ax.set_yticklabels(np.arange(0.0, 1.1, 0.2), fontdict=Font)
        self._ax.set_ylabel("Spectral Radiance (W/(m$^2$*sr*nm))", fontdict=Font)

        self._ax.grid(True)  # Grid On

    def _updateFigures(self):
        Font = {'family': 'Tahoma',
                'weight': 'bold',
                'size': 10}

        self._ax.clear()

        maxY = 0.0

        x = np.arange(380, 781)
        y = np.random.rand(401)

        self._ax.plot(x, y, 'r', label="Data")

     maxY = max(y)
        if maxY <= 0:
            self._initializeFigure()
        else:
            self._fig.subplots_adjust(left=0.11, top=0.92, right=0.95, bottom=0.1)
            # Abscissa
            self._ax.set_xlim([380, 780])
            self._ax.set_xticks([380, 460, 540, 620, 700, 780])
            self._ax.set_xticklabels([380, 460, 540, 620, 700, 780], fontdict=Font)
            self._ax.set_xlabel("Wavelength (nm)", fontdict=Font)
            # Ordinate
            self._ax.set_ylim([0.0, maxY])
            self._ax.set_yticks([0.0, maxY / 4.0, maxY / 2.0, maxY * 3 / 4.0, maxY])
            self._ax.set_yticklabels(
                ["%.1e" % 0.0, "%.1e" % (maxY / 4.0), "%.1e" % (maxY / 2.0), "%.1e" % (maxY * 3.0 / 4.0),
                 "%.1e" % maxY], fontdict=Font)
            self._ax.set_ylabel("Spectral Radiance (W/(m$^2$*sr*nm))", fontdict=Font)

        self._ax.grid(True)
        self._ax.legend(loc="best", fontsize="small").draggable(state=True)  # Legend
        self._canvas.draw()

    @pyqtSlot()
    def on_plotPushButton_clicked(self):
        self._updateFigures()

初始界面如图2所示:

图2 GUI初始界面

3) 点击plot按键后

界面显示见图3:

 

图3 点击Plot按键后界面

 

 

Matplotlib作为Python中著名的数据可视化工具,其官网也提供了在PyQt4中使用的源码,这里举一个应用实例,...

美高梅游戏平台网站,一个典型的GUI应用程序可以抽象为:主界面(菜单栏、工具栏、状态栏、内容区域),二级界面(模态、非模态),信息提示(Tooltip),程序图标等组成。本篇根据作者使用PyQt5编写的一个工具,介绍如何使用PyQt5构建一个典型的GUI应用。

1. 主界面

QMainWindow类提供一个有菜单条、锚接窗口(例如工具条)和一个状态条的主应用程序窗口。主窗口通常用在提供一个大的中央窗口部件(例如文本编辑或者绘制画布)以及周围菜单、工具条和一个状态条。QMainWindow常常被继承,因为这使得封装中央部件、菜单和工具条以及窗口状态变得更容易。

 

菜单栏

创建菜单的代码如下:

self.addMenu = self.menuBar().addMenu("&添加")
self.addMenu.addAction(self.addAvatarAct)
self.addMenu.addAction(self.addAvatarSetAct)
self.addMenu.addAction(self.addAvatarDecorationAct)
self.modifyMenu = self.menuBar().addMenu("&修改")
self.modifyMenu.addAction(self.modifyAvatarAct)
self.modifyMenu.addAction(self.modifyAvatarSetAct)
self.settingMenu = self.menuBar().addMenu("&设置")
self.settingMenu.addAction(self.settingAct)

其中每个菜单项,关联一个QAction,定义了图标、菜单名、回调函数、快捷键等等,这里没有设置快捷键。

self.addAvatarAct = QAction(QIcon("res/ico/addAvatar.ico"), "&Add Avatar", self, triggered=self.addAvatar)
self.addAvatarSetAct = QAction(QIcon("res/ico/addAvatarSet.ico"), "&Add AvatarSet", self, triggered=self.addAvatarSet)
self.addAvatarDecorationAct = QAction(QIcon("res/ico/addAvatarDecoration.ico"), "&Add AvatarDecoration", self, triggered=self.addAvatarDecoration)
self.modifyAvatarAct = QAction(QIcon("res/ico/modifyAvatar.ico"), "&Modify Avatar or Decoration", self, triggered=self.modifyAvatar)
self.modifyAvatarSetAct = QAction(QIcon("res/ico/modifyAvatarSet.ico"), "&Modify AvatarSet", self, triggered=self.modifyAvatarSet)
self.settingAct = QAction(QIcon("res/ico/settingPath.ico"), "&路径", self, triggered=self.settingPath)
self.homeAct = QAction(QIcon("res/ico/home.ico"), "&首页", self, triggered=self.homePage)

 

说明:QAction类提供了一个可以同时出现在菜单和工具条上的抽象用户界面操作。

在图形用户界面应用程序中很多命令可以通过菜单选项、工具条按钮和键盘快捷键调用。因为同一个操作将会被执行,而与它的调用方法无关,并且因为菜单和工具条必须保持同步,所以提供一个操作这样的命令很有用。一个操作可以被添加到菜单和工具条中并且将会自动使它们同步。例如,如果用户按下“加粗”工具条按钮,“加粗”菜单项将会自动被选中。

QAction可以包含图标、菜单文本、快捷键、状态条文本、这是什么文本和工具提示。它们可以分别通过setIconSet()、setText()、setMenuText()、setToolTip()、setStatusTip()、setWhatsThis()和setAccel()来设置。

 

工具栏

创建工具栏的代码如下:

self.toolbar = self.addToolBar('Home')
self.toolbar.addAction(self.homeAct)
self.toolbar = self.addToolBar('AddAvatar')
self.toolbar.addAction(self.addAvatarAct)
self.toolbar = self.addToolBar('AddAvatarDecoration')
self.toolbar.addAction(self.addAvatarDecorationAct)
self.toolbar = self.addToolBar('AddAvatarSet')
self.toolbar.addAction(self.addAvatarSetAct)
self.toolbar = self.addToolBar('ModifyAvatar')
self.toolbar.addAction(self.modifyAvatarAct)
self.toolbar = self.addToolBar('ModifyAvatarSet')
self.toolbar.addAction(self.modifyAvatarSetAct)

工具栏项也需要关联一个QAction,可以和菜单项共用一个QAction,即一个QAction可以被关联到多个地方。

状态栏

设置状态栏,只需要:

self.statusBar().showMessage("数据加载完成")

第一次调用self.statusBar()获取工具栏时,会初始化工具栏实例,后面再次调用不会在创建新的实例。

程序图标

程序图标分为2个:程序窗口图标;执行文件的图标。

l  setWindowIcon(QIcon(“res/ico/icon.ico”))设置程序窗口的图标

l  执行文件的图标,通过打包工具设置

2. UI布局

PyQt的布局系统提供了一个规定子窗口部件布局的简单的和强有力的方式。当你一旦规定了合理的布局,你就会获得如下利益:

l  布置子窗口部件。

l  最高层窗口部件可感知的默认大小。

l  最高层窗口部件可感知的最小大小。

l  调整大小的处理。

l  当内容改变的时候自动更新:

n  字体大小、文本或者子窗口部件的其它内容。

n  隐藏或者显示子窗口部件。

n  移去一些子窗口部件。

PyQt支持的布局方式有很多,如下表所示:

布局相关类

作用

QBoxLayout

Lines up child widgets horizontally or vertically

QButtonGroup

Container to organize groups of button widgets

QFormLayout

Manages forms of input widgets and their associated labels

QGraphicsAnchor

Represents an anchor between two items in a QGraphicsAnchorLayout

QGraphicsAnchorLayout

Layout where one can anchor widgets together in Graphics View

QGridLayout

Lays out widgets in a grid

QGroupBox

Group box frame with a title

QHBoxLayout

Lines up widgets horizontally

QLayout

The base class of geometry managers

QLayoutItem

Abstract item that a QLayout manipulates

QSizePolicy

Layout attribute describing horizontal and vertical resizing policy

QSpacerItem

Blank space in a layout

QStackedLayout

Stack of widgets where only one widget is visible at a time

QStackedWidget

Stack of widgets where only one widget is visible at a time

QVBoxLayout

Lines up widgets vertically

QWidgetItem

Layout item that represents a widget

 

其中使用比较多的是以下布局方式(或者说是我使用比较多,不代表大家):

  • 水平布局 QHBoxLayout
  • 垂直布局 QVBoxLayout
  • 网格布局 QGridLayout

 

 

水平布局

水平布局(QHBoxLayout)顾名思义,将空间水平切成多段,然后通过addWidget、addItem将widget填充指定的位置。如下代码即实现了上图中,适合角色选择的水平布局:

hbox = QHBoxLayout()
self.roleChkBoxGroup.setLayout(hbox)
for _, v in sorted(ParseKeywords.profession.items()):
         checkBox = QRadioButton(v["cname"] + " " + str(v["value"]))
         hbox.addWidget(checkBox)

删除一个控件,使用removeWidget,或者调用QWidget.hide()一样可以从布局中删除,直到QWidget.show()被调用。下面的垂直布局、网格布局,甚至其他布局都是注意的。

垂直布局

垂直布局(QVBoxLayout)顾名思义,将空间垂直切成多段,然后通过addWidget、addItem将widget填充指定的位置。如下代码即实现了上图中,细节信息的垂直布局(垂直布局中,还嵌套了水平布局):

vbox = QVBoxLayout()
groupBox.setLayout(vbox)

count = QWidget()
hbox = QHBoxLayout()
countLabel = QLabel("细节数目:")
hbox.addWidget(countLabel)
self.countSpineBox = QSpinBox()
self.countSpineBox.setRange(0, 10)
self.countSpineBox.valueChanged.connect(self.countSpineValueChanged) hbox.addWidget(self.countSpineBox)
hbox.addStretch()
count.setLayout(hbox)
**vbox.addWidget(count)   #垂直布局,添加widget1

**

self.detailTable = QTableWidget()
self.detailTable.setColumnCount(9)
self.detailTable.setHorizontalHeaderLabels(
         ['有效期', '货币类型', '价格', '普通折扣价', '蓝钻价', '蓝钻折扣价', '超级蓝钻折扣价', '赠送礼包ID', '快捷购买'])
vbox.addWidget(self.detailTable)   #垂直布局,添加widget2

垂直布局中,还嵌套了水平布局。

说明:QHBoxLayout、QVBoxLayout都是继承自QBoxLayout,为了更好的控制布局,都继承了以下方法:

l  QBoxLayout.addSpacing (size)

   添加一个不能伸缩的空间(一个QSpacerItem),其宽度设置为size到布局末尾。框布局提供了默认的边距margin和spacing,这是额外添加的空间。

l  QBoxLayout.addStretch(stretch)

   添加一个可伸缩的空间(一个QSpacerItem),设0为最小值并且伸缩因子为stretch直到布局末尾

 

网络布局

网格布局(QGridLayout)顾名思义,将空间划分成多行多列的网络,然后通过addWidget、addItem将widget填充到指定的单元格(cell)。这个比较像网页中使用table布局的思路。下面的代码即创建上图中的网格布局:

grid = QGridLayout()
grid.addWidget(setidLabel, 0, 0)
grid.addWidget(self.setidLineEdit, 0, 1)
grid.addWidget(QLabel("(第1位-2,第2~3位-表示适用角色,第4~5位-挂点位置,第6~8位-序号)"), 0, 2)
grid.addWidget(subidLabel, 1, 0)
grid.addWidget(self.subidLineEdit, 1, 1)
grid.addWidget(QLabel("(套装包含的物品,多个物品适用逗号分隔;必须在套装之前添加)"), 1, 2)
grid.addWidget(fashionLabel, 2, 0)
grid.addWidget(self.fashionLineEdit, 2, 1)
grid.addWidget(nameLabel, 3, 0)
grid.addWidget(self.nameLineEdit, 3, 1)
grid.addWidget(descLabel, 4, 0)
grid.addWidget(self.descLineEdit, 4, 1)
grid.addWidget(marketTagLabel, 5, 0)
grid.addWidget(self.tagCombox, 5, 1)
grid.addWidget(recommendLabel, 6, 0)
grid.addWidget(self.recommendCombox, 6, 1)
grid.addWidget(roleLabel, 8, 0)
grid.addWidget(self.roleChkBoxGroup, 8, 1)
grid.addWidget(beginLabel, 9, 0)
grid.addWidget(self.beginTime, 9, 1)
grid.addWidget(endLabel, 10, 0)
grid.addWidget(self.endTime, 10, 1)

gridWidget = QWidget()
gridWidget.setLayout(grid)

上述往网格中添加的widget都是占一个单元格的情况,其实还支持占用几个单元格。如下代码,往网格中的第二行、第一列添加一个widget,占用1行、2列:

grid.addWidget(self.createDetail(), 1, 0, 1, 2)

网格布局默认是均分每列,为了更好的控制布局,QGridLayout为每列提供了最小宽度(setColumnMinimumWidth())、伸缩因子(setColumnStretch()),为每行提供了最小高度(setRowMinimumHeight())、伸缩因子(setRowStretch())。最小宽/高度很好理解,伸缩因子如下面代码,设置了第二列和三列的比例是1:2。

layout.setColumnStretch(1, 10)
layout.setColumnStretch(2, 20)

 

3. 二级弹窗

QDialog类是对话框窗口的基类。对话框窗口是主要用于短期任务以及和用户进行简要通讯的顶级窗口。QDialog可以是模态对话框也可以是非模态对话框。QDialog支持扩展性并且可以提供返回值。它们可以有默认按钮。

内置对话框

内置常用的对话框有:QColorDialog、QErrorMessage、QFileDialog、QFontDialog、QInputDialog、QMessageBox、QProgressDialog、QTabDialog、QWizard。

内置的对话框提供了一些常用的功能,使用起来也必将遍历。编写该工具使用到了,选择文件、目录的对话框QFileDialog。

本文由美高梅游戏平台网站发布于鲜果干果,转载请注明出处:Matplotlib在PyQt4的应用,matplotlibpyqt4

关键词:

最火资讯