python3+PyQt5实现柱状图


Posted in Python onApril 24, 2018

本文通过Python3+pyqt5实现了python Qt GUI 快速编程的16章的excise例子。

#!/usr/bin/env python3

import random
import sys
from PyQt5.QtCore import (QAbstractListModel, QAbstractTableModel,
  QModelIndex, QSize, QTimer, QVariant, Qt,pyqtSignal)
from PyQt5.QtWidgets import (QApplication, QDialog, QHBoxLayout,
  QListView, QSpinBox, QStyledItemDelegate,QStyleOptionViewItem, QWidget)
from PyQt5.QtGui import QColor,QPainter,QPixmap

class BarGraphModel(QAbstractListModel):
 dataChanged=pyqtSignal(QModelIndex,QModelIndex)
 def __init__(self):
  super(BarGraphModel, self).__init__()
  self.__data = []
  self.__colors = {}
  self.minValue = 0
  self.maxValue = 0


 def rowCount(self, index=QModelIndex()):
  return len(self.__data)


 def insertRows(self, row, count):
  extra = row + count
  if extra >= len(self.__data):
   self.beginInsertRows(QModelIndex(), row, row + count - 1)
   self.__data.extend([0] * (extra - len(self.__data) + 1))
   self.endInsertRows()
   return True
  return False


 def flags(self, index):
  #return (QAbstractTableModel.flags(self, index)|Qt.ItemIsEditable)
  return (QAbstractListModel.flags(self, index)|Qt.ItemIsEditable)

 def setData(self, index, value, role=Qt.DisplayRole):
  row = index.row()
  if not index.isValid() or 0 > row >= len(self.__data):
   return False
  changed = False
  if role == Qt.DisplayRole:
   value = value
   self.__data[row] = value
   if self.minValue > value:
    self.minValue = value
   if self.maxValue < value:
    self.maxValue = value
   changed = True
  elif role == Qt.UserRole:
   self.__colors[row] = value
   #self.emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
   #   index, index)
   self.dataChanged[QModelIndex,QModelIndex].emit(index, index)
   changed = True
  if changed:
   #self.emit(SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
    #   index, index)
   self.dataChanged[QModelIndex,QModelIndex].emit(index, index)
  return changed


 def data(self, index, role=Qt.DisplayRole):
  row = index.row()
  if not index.isValid() or 0 > row >= len(self.__data):
   return QVariant()
  if role == Qt.DisplayRole:
   return self.__data[row]
  if role == Qt.UserRole:
   return QVariant(self.__colors.get(row,
     QColor(Qt.red)))
  if role == Qt.DecorationRole:
   color = QColor(self.__colors.get(row,
     QColor(Qt.red)))
   pixmap = QPixmap(20, 20)
   pixmap.fill(color)
   return QVariant(pixmap)
  return QVariant()


class BarGraphDelegate(QStyledItemDelegate):

 def __init__(self, minimum=0, maximum=100, parent=None):
  super(BarGraphDelegate, self).__init__(parent)
  self.minimum = minimum
  self.maximum = maximum


 def paint(self, painter, option, index):
  myoption = QStyleOptionViewItem(option)
  myoption.displayAlignment |= (Qt.AlignRight|Qt.AlignVCenter)
  QStyledItemDelegate.paint(self, painter, myoption, index)


 def createEditor(self, parent, option, index):
  spinbox = QSpinBox(parent)
  spinbox.setRange(self.minimum, self.maximum)
  spinbox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
  return spinbox


 def setEditorData(self, editor, index):
  value = index.model().data(index, Qt.DisplayRole)
  editor.setValue(value)


 def setModelData(self, editor, model, index):
  editor.interpretText()
  model.setData(index, editor.value())


class BarGraphView(QWidget):

 WIDTH = 20

 def __init__(self, parent=None):
  super(BarGraphView, self).__init__(parent)
  self.model = None


 def setModel(self, model):
  self.model = model
  #self.connect(self.model,
  #  SIGNAL("dataChanged(QModelIndex,QModelIndex)"),
  #  self.update)
  self.model.dataChanged[QModelIndex,QModelIndex].connect(self.update)
  #self.connect(self.model, SIGNAL("modelReset()"), self.update)
  self.model.modelReset.connect(self.update)


 def sizeHint(self):
  return self.minimumSizeHint()


 def minimumSizeHint(self):
  if self.model is None:
   return QSize(BarGraphView.WIDTH * 10, 100)
  return QSize(BarGraphView.WIDTH * self.model.rowCount(), 100)


 def paintEvent(self, event):
  if self.model is None:
   return
  painter = QPainter(self)
  painter.setRenderHint(QPainter.Antialiasing)
  span = self.model.maxValue - self.model.minValue
  painter.setWindow(0, 0, BarGraphView.WIDTH * self.model.rowCount(),
       span)
  for row in range(self.model.rowCount()):
   x = row * BarGraphView.WIDTH
   index = self.model.index(row)
   color = QColor(self.model.data(index, Qt.UserRole))
   y = self.model.data(index)
   painter.fillRect(x, span - y, BarGraphView.WIDTH, y, color)


class MainForm(QDialog):

 def __init__(self, parent=None):
  super(MainForm, self).__init__(parent)

  self.model = BarGraphModel()
  self.barGraphView = BarGraphView()
  self.barGraphView.setModel(self.model)
  self.listView = QListView()
  self.listView.setModel(self.model)
  self.listView.setItemDelegate(BarGraphDelegate(0, 1000, self))
  self.listView.setMaximumWidth(100)
  self.listView.setEditTriggers(QListView.DoubleClicked|
          QListView.EditKeyPressed)
  layout = QHBoxLayout()
  layout.addWidget(self.listView)
  layout.addWidget(self.barGraphView, 1)
  self.setLayout(layout)

  self.setWindowTitle("Bar Grapher")
  QTimer.singleShot(0, self.initialLoad)


 def initialLoad(self):
  # Generate fake data
  count = 20
  self.model.insertRows(0, count - 1)
  for row in range(count):
   value = random.randint(1, 150)
   color = QColor(random.randint(0, 255), random.randint(0, 255),
       random.randint(0, 255))
   index = self.model.index(row)
   self.model.setData(index, value)
   self.model.setData(index, QVariant(color), Qt.UserRole)


app = QApplication(sys.argv)
form = MainForm()
form.resize(600, 400)
form.show()
app.exec_()

运行结果:

python3+PyQt5实现柱状图

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python3之读取连接过的网络并定位的方法
Apr 22 Python
Python 实现某个功能每隔一段时间被执行一次的功能方法
Oct 14 Python
python 解压pkl文件的方法
Oct 25 Python
使用urllib库的urlretrieve()方法下载网络文件到本地的方法
Dec 19 Python
Python3 实现文件批量重命名示例代码
Jun 03 Python
使用coverage统计python web项目代码覆盖率的方法详解
Aug 05 Python
浅谈Pytorch中的自动求导函数backward()所需参数的含义
Feb 29 Python
django 多数据库及分库实现方式
Apr 01 Python
keras读取h5文件load_weights、load代码操作
Jun 12 Python
Python虚拟环境的创建和包下载过程分析
Jun 19 Python
python求解汉诺塔游戏
Jul 09 Python
django如何自定义manage.py管理命令
Apr 27 Python
python3+PyQt5自定义视图详解
Apr 24 #Python
python自动重试第三方包retrying模块的方法
Apr 24 #Python
python3+PyQt5泛型委托详解
Apr 24 #Python
python去除扩展名的实例讲解
Apr 23 #Python
python3 遍历删除特定后缀名文件的方法
Apr 23 #Python
将TensorFlow的模型网络导出为单个文件的方法
Apr 23 #Python
tensorflow1.0学习之模型的保存与恢复(Saver)
Apr 23 #Python
You might like
PHP GD库生成图像的几个函数总结
2014/11/19 PHP
php写入mysql中文乱码的实例解决方法
2019/09/17 PHP
php 实现银联商务H5支付的示例代码
2019/10/12 PHP
js innerHTML 改变div内容的方法
2013/08/03 Javascript
详解jQuery插件开发中的extend方法
2013/11/19 Javascript
Javascript监视变量变化的方法
2015/06/09 Javascript
jQuery插件之Tocify动态节点目录菜单生成器附源码下载
2016/01/08 Javascript
ECharts仪表盘实例代码(附源码下载)
2016/02/18 Javascript
基于Jquery插件实现跨域异步上传文件功能
2016/04/26 Javascript
详解NodeJs支付宝移动支付签名及验签
2017/01/06 NodeJs
Angular.JS中select下拉框设置value的方法
2017/06/20 Javascript
关于使用js算总价的问题
2017/06/23 Javascript
基于Vue开发数字输入框组件
2017/12/19 Javascript
高性能的javascript之加载顺序与执行原理篇
2018/01/14 Javascript
在 Angular中 使用 Lodash 的方法
2018/02/11 Javascript
浅谈vue中组件绑定事件时是否加.native
2019/11/09 Javascript
vue实现轮播图帧率播放
2021/01/26 Vue.js
Python按行读取文件的实现方法【小文件和大文件读取】
2016/09/19 Python
python subprocess 杀掉全部派生的子进程方法
2017/01/16 Python
pycharm远程调试openstack代码
2017/11/21 Python
Django基础知识 URL路由系统详解
2019/07/18 Python
详解Python中的正斜杠与反斜杠
2019/08/09 Python
Python使用Pandas读写Excel实例解析
2019/11/19 Python
tensorflow之获取tensor的shape作为max_pool的ksize实例
2020/01/04 Python
python实现控制台输出颜色
2021/03/02 Python
CSS3 display知识详解
2015/11/25 HTML / CSS
HTML5未来发展趋势
2016/02/01 HTML / CSS
Speedo速比涛中国官方网站:全球领先泳装运动品牌
2018/04/24 全球购物
从当地商店送来的杂货:Instacart
2018/08/19 全球购物
大四学年自我鉴定
2013/11/13 职场文书
环境科学专业个人求职的自我评价
2013/11/28 职场文书
中式餐厅创业计划书范文
2014/01/23 职场文书
质量承诺书范文
2014/03/27 职场文书
出纳工作检讨书
2014/10/18 职场文书
2015年收银员个人工作总结
2015/04/01 职场文书
PostgreSQL将数据加载到buffer cache中操作方法
2021/04/16 PostgreSQL