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中统计函数运行耗时的方法
May 05 Python
Python找出list中最常出现元素的方法
Jun 14 Python
python魔法方法-自定义序列详解
Jul 21 Python
Python Flask-web表单使用详解
Nov 18 Python
使用Anaconda3建立虚拟独立的python2.7环境方法
Jun 11 Python
python实现桌面托盘气泡提示
Jul 29 Python
python redis连接 有序集合去重的代码
Aug 04 Python
基于Python数据结构之递归与回溯搜索
Feb 26 Python
Python计算IV值的示例讲解
Feb 28 Python
Mac中PyCharm配置Anaconda环境的方法
Mar 04 Python
keras实现多GPU或指定GPU的使用介绍
Jun 17 Python
Python中的matplotlib绘制百分比堆叠柱状图,并为每一个类别设置不同的填充图案
Apr 20 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 移除数组重复元素的一点说明
2008/11/27 PHP
php创建无限级树型菜单
2015/11/05 PHP
利用php获得flv视频长度的实例代码
2017/10/26 PHP
js checkbox(复选框) 使用集锦
2009/04/28 Javascript
Jquery中dialog属性小记
2010/09/03 Javascript
nodejs分页类代码分享
2014/06/17 NodeJs
JavaScript中的变量作用域介绍
2014/12/31 Javascript
jQuery搜索子元素的方法
2015/02/10 Javascript
javascript验证身份证号
2015/03/03 Javascript
JavaScript动态修改弹出窗口大小的方法
2015/04/06 Javascript
jQuery获取table行数并输出单元格内容的实现方法
2016/06/30 Javascript
浅谈JS中的bind方法与函数柯里化
2016/08/10 Javascript
微信小程序 教程之注册页面
2016/10/17 Javascript
值得收藏的vuejs安装教程
2017/11/21 Javascript
利用Console来Debug的10个高级技巧汇总
2018/03/26 Javascript
深入理解 Koa 框架中间件原理
2018/10/18 Javascript
vuedraggable+element ui实现页面控件拖拽排序效果
2020/07/29 Javascript
ant-design-vue中的select选择器,对输入值的进行筛选操作
2020/10/24 Javascript
vue+Element-ui实现登录注册表单
2020/11/17 Javascript
[03:40]DOTA2亚洲邀请赛小组赛第二日 赛事回顾
2015/01/31 DOTA
python中关于时间和日期函数的常用计算总结(time和datatime)
2013/03/08 Python
python在windows命令行下输出彩色文字的方法
2015/03/19 Python
Python+selenium 获取一组元素属性值的实例
2018/06/22 Python
Python中xml和json格式相互转换操作示例
2018/12/05 Python
Python提取特定时间段内数据的方法实例
2019/04/01 Python
HTML5 Canvas 起步(1) - 基本概念
2009/05/12 HTML / CSS
canvas使用注意点总结
2013/07/19 HTML / CSS
2014自主招生自荐信策略
2014/01/27 职场文书
2014年社区植树节活动方案
2014/02/28 职场文书
个人求职信范文
2014/05/24 职场文书
党员先进性教育整改措施
2014/09/18 职场文书
公安干警正风肃纪心得体会
2016/01/15 职场文书
学校教代会开幕词
2016/03/04 职场文书
python控制台打印log输出重复的解决方法
2021/05/14 Python
python简单验证码识别的实现过程
2021/06/20 Python
Apache SkyWalking 监控 MySQL Server 实战解析
2022/09/23 Servers