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脚本实现下载合并SAE日志
Feb 10 Python
利用Python绘制MySQL数据图实现数据可视化
Mar 30 Python
在Python的循环体中使用else语句的方法
Mar 30 Python
Python实现的科学计算器功能示例
Aug 04 Python
Python+matplotlib+numpy绘制精美的条形统计图
Jan 02 Python
Centos部署django服务nginx+uwsgi的方法
Jan 02 Python
flask应用部署到服务器的方法
Jul 12 Python
200行python代码实现2048游戏
Jul 17 Python
python2与python3爬虫中get与post对比解析
Sep 18 Python
python ftplib模块使用代码实例
Dec 31 Python
如何使用python切换hosts文件
Apr 29 Python
python对输出的奇数偶数排序实例代码
Dec 04 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
星际争霸教主Flash的ID由来:你永远不会知道他之前的ID是www!
2019/01/18 星际争霸
php中将汉字转换成拼音的函数代码
2012/09/08 PHP
解析argc argv在php中的应用
2013/06/24 PHP
完美的php分页类
2017/10/24 PHP
PHP使用Session实现上传进度功能详解
2019/08/06 PHP
Javascript实例教程(19) 使用HoTMetal(6)
2006/12/23 Javascript
jquery命令汇总,方便使用jquery的朋友
2012/06/26 Javascript
Javascript 按位与运算符 (&amp;)使用介绍
2014/02/04 Javascript
Jquery 返回json数据在IE浏览器中提示下载的问题
2014/05/18 Javascript
IE及IE6浏览器中判断JS文件加载成功失败的方法
2015/02/18 Javascript
Jquery解析json字符串及json数组的方法
2015/05/29 Javascript
jQuery实现带渐显效果的人物多级关系图代码
2015/10/16 Javascript
JCrop+ajaxUpload 图像切割上传的实例代码
2016/07/20 Javascript
如何检测JavaScript的各种类型
2016/07/30 Javascript
vue.js 表格分页ajax 异步加载数据
2016/10/18 Javascript
半个小时学json(json传递示例)
2016/12/25 Javascript
浅谈通过JS拦截 pushState和replaceState事件
2017/07/21 Javascript
nodejs socket服务端和客户端简单通信功能
2017/09/14 NodeJs
element ui 表格动态列显示空白bug 修复方法
2018/09/04 Javascript
JS+CSS实现炫酷光感效果
2020/09/05 Javascript
Python 基于Twisted框架的文件夹网络传输源码
2016/08/28 Python
Tensorflow 自带可视化Tensorboard使用方法(附项目代码)
2018/02/10 Python
pandas pivot_table() 按日期分多列数据的方法
2018/11/16 Python
Python多线程处理实例详解【单进程/多进程】
2019/01/30 Python
Python3.5多进程原理与用法实例分析
2019/04/05 Python
OpenCV里的imshow()和Matplotlib.pyplot的imshow()的实现
2019/11/25 Python
Python sys模块常用方法解析
2020/02/20 Python
python多进程使用函数封装实例
2020/05/02 Python
浅谈django框架集成swagger以及自定义参数问题
2020/07/07 Python
Microsoft Advertising美国:微软搜索广告
2019/05/01 全球购物
荷兰音乐会和音乐剧门票订购网站:Topticketshop
2019/08/27 全球购物
制定岗位职责的原则
2013/11/08 职场文书
质监局领导班子对照检查材料思想汇报
2014/09/27 职场文书
2015年大学辅导员工作总结
2015/05/12 职场文书
2015选调生工作总结
2015/07/24 职场文书
2015年十月一日放假通知
2015/08/18 职场文书