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 相关文章推荐
python str与repr的区别
Mar 23 Python
Python中使用Boolean操作符做真值测试实例
Jan 30 Python
简单说明Python中的装饰器的用法
Apr 24 Python
python 3.6 tkinter+urllib+json实现火车车次信息查询功能
Dec 20 Python
python+selenium实现163邮箱自动登陆的方法
Dec 31 Python
详解如何将python3.6软件的py文件打包成exe程序
Oct 09 Python
python3.6使用urllib完成下载的实例
Dec 19 Python
python实现石头剪刀布程序
Jan 20 Python
Django中使用 Closure Table 储存无限分级数据
Jun 06 Python
pycharm中显示CSS提示的知识点总结
Jul 29 Python
利用python为PostgreSQL的表自动添加分区
Jan 18 Python
python绘制高斯曲线
Feb 19 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
我的论坛源代码(二)
2006/10/09 PHP
PHP实现支持GET,POST,Multipart/form-data的HTTP请求类
2014/09/24 PHP
LAMP环境使用Composer安装Laravel的方法
2017/03/25 PHP
PHP实现向关联数组指定的Key之前插入元素的方法
2017/06/06 PHP
jquery属性选择器not has怎么写 行悬停高亮显示
2013/11/13 Javascript
Bootstrap前端开发案例二
2016/06/17 Javascript
详解vue之页面缓存问题(基于2.0)
2017/01/10 Javascript
self.attachevent is not a function的解决方法
2017/04/04 Javascript
nodejs socket服务端和客户端简单通信功能
2017/09/14 NodeJs
JavaScript 自定义事件之我见
2017/09/25 Javascript
[04:02]2014DOTA2国际邀请赛 BBC每日综述中国战队将再度登顶
2014/07/21 DOTA
python中将字典转换成其json字符串
2014/07/16 Python
python实现数值积分的Simpson方法实例分析
2015/06/05 Python
python matplotlib中文显示参数设置解析
2017/12/15 Python
详解Python判定IP地址合法性的三种方法
2018/03/06 Python
python直接获取API传递回来的参数方法
2018/12/17 Python
Python线程池模块ThreadPoolExecutor用法分析
2018/12/28 Python
对Xpath 获取子标签下所有文本的方法详解
2019/01/02 Python
Django数据库类库MySQLdb使用详解
2019/04/28 Python
python的常见矩阵运算(小结)
2019/08/07 Python
使用浏览器访问python写的服务器程序
2019/10/10 Python
浅谈Python中的字符串
2020/06/10 Python
css3针对移动端卡顿问题的解决(动画性能优化)
2020/02/14 HTML / CSS
舞会礼服和舞会鞋:PromGirl
2019/04/22 全球购物
工程力学专业毕业生求职信
2013/10/06 职场文书
自主招生自荐信
2013/12/08 职场文书
入党介绍人评语
2014/05/06 职场文书
财政局党的群众路线教育实践活动整改方案
2014/09/21 职场文书
2014年党员整改措施
2014/10/24 职场文书
满月酒邀请函
2015/01/30 职场文书
会议通知范文
2015/04/15 职场文书
2015年食堂工作总结报告
2015/04/23 职场文书
终止合同协议书范本
2016/03/22 职场文书
go语言中fallthrough的用法说明
2021/05/06 Golang
python plt.plot bar 如何设置绘图尺寸大小
2021/06/01 Python
MySQL系列之十三 MySQL的复制
2021/07/02 MySQL