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 相关文章推荐
PHP webshell检查工具 python实现代码
Sep 15 Python
Python中的文件和目录操作实现代码
Mar 13 Python
python list转dict示例分享
Jan 28 Python
python中元类用法实例
Oct 10 Python
WINDOWS 同时安装 python2 python3 后 pip 错误的解决方法
Mar 16 Python
python+opencv轮廓检测代码解析
Jan 05 Python
python+pandas生成指定日期和重采样的方法
Apr 11 Python
numpy 计算两个数组重复程度的方法
Nov 07 Python
python实现简单的单变量线性回归方法
Nov 08 Python
jupyter notebook中美观显示矩阵实例
Apr 17 Python
Python实例教程之检索输出月份日历表
Dec 16 Python
python 基于opencv实现高斯平滑
Dec 18 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设计模式之观察者模式的应用详解
2013/05/21 PHP
PHP常见字符串操作函数与用法总结
2019/03/04 PHP
用js实现多域名不同文件的调用方法
2007/01/12 Javascript
用javascript实现画板的代码
2007/09/05 Javascript
JS应用之禁止抓屏、复制、打印
2008/02/21 Javascript
各种效果的jquery ui(接口)介绍
2008/09/17 Javascript
Extjs Gird 支持中文拼音排序实现代码
2013/04/15 Javascript
Nodejs中调用系统命令、Shell脚本和Python脚本的方法和实例
2015/01/01 NodeJs
JS修改iframe页面背景颜色的方法
2015/04/01 Javascript
javascript实现验证IP地址等相关信息代码
2015/05/10 Javascript
js文本框走动跑马灯效果代码分享
2015/08/25 Javascript
jquery悬浮提示框完整实例
2016/01/13 Javascript
Javascript的表单验证-提交表单
2016/03/18 Javascript
AngularJS基础 ng-srcset 指令简单示例
2016/08/03 Javascript
js获取浏览器和屏幕的各种宽度高度
2017/02/22 Javascript
echarts饼图扇区添加点击事件的实例
2017/10/16 Javascript
layui表单验证select下拉框实现验证的方法
2019/09/05 Javascript
[04:28]2014DOTA2国际邀请赛 采访小兔子LGD挺进钥匙体育馆
2014/07/14 DOTA
详解MySQL数据类型int(M)中M的含义
2016/11/20 Python
Python中str is not callable问题详解及解决办法
2017/02/10 Python
numpy中以文本的方式存储以及读取数据方法
2018/06/04 Python
Python爬虫框架Scrapy基本用法入门教程
2018/07/26 Python
关于python列表增加元素的三种操作方法
2018/08/22 Python
Python中six模块基础用法
2019/12/08 Python
python在一个范围内取随机数的简单实例
2020/08/16 Python
html5中为audio标签增加停止按钮动作实现方法
2013/01/04 HTML / CSS
HMV日本官网:全球知名的音乐、DVD和电脑游戏零售巨头
2016/08/13 全球购物
航空大学应届生求职信
2013/11/10 职场文书
教师的实习鉴定
2013/12/15 职场文书
自我评价是什么
2014/01/04 职场文书
大学理论知识学习自我鉴定
2014/04/28 职场文书
2014年依法行政工作总结
2014/11/19 职场文书
pycharm2021激活码使用教程(永久激活亲测可用)
2021/03/30 Python
上帝为你开了一扇窗之Tkinter常用函数详解
2021/06/02 Python
Python中异常处理用法
2021/11/27 Python
利用JuiceFS使MySQL 备份验证性能提升 10 倍
2022/03/17 MySQL