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 29 Python
Python内置函数reversed()用法分析
Mar 20 Python
Python中创建二维数组
Oct 17 Python
Windows下Python3.6安装第三方模块的方法
Nov 22 Python
python画双y轴图像的示例代码
Jul 07 Python
python使用opencv实现马赛克效果示例
Sep 28 Python
Python 装饰器@,对函数进行功能扩展操作示例【开闭原则】
Oct 17 Python
python读取图片的几种方式及图像宽和高的存储顺序
Feb 11 Python
Python如何省略括号方法详解
Mar 21 Python
Python Flask框架实现简单加法工具过程解析
Jun 03 Python
Windows 平台做 Python 开发的最佳组合(推荐)
Jul 27 Python
Python 恐龙跑跑小游戏实现流程
Feb 15 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中PDO解决中文乱码问题的一些补充
2010/09/06 PHP
CMS中PHP判断系统是否已经安装的方法示例
2014/07/26 PHP
PHP如何获取当前主机、域名、网址、路径、端口等参数
2017/06/09 PHP
JavaScript 获取用户客户端操作系统版本
2009/08/25 Javascript
jQuery实现的多选框多级联动插件
2014/05/02 Javascript
JS判断、校验MAC地址的2个实例
2014/05/05 Javascript
js基于setTimeout与setInterval实现多线程
2016/06/17 Javascript
Wireshark基本介绍和学习TCP三次握手
2016/08/15 Javascript
js监听键盘事件的方法_原生和jquery的区别详解
2016/10/10 Javascript
BootStrap 导航条实例代码
2017/05/18 Javascript
Vue列表页渲染优化详解
2017/07/24 Javascript
浅谈Vue网络请求之interceptors实际应用
2018/02/28 Javascript
vue全局使用axios的方法实例详解
2018/11/22 Javascript
详解React中合并单元格的正确写法
2019/01/08 Javascript
解决微信小程序调用moveToLocation失效问题【超简单】
2019/04/12 Javascript
vue实现登录、注册、退出、跳转等功能
2020/12/23 Vue.js
python杀死一个线程的方法
2015/09/06 Python
Python编程中time模块的一些关键用法解析
2016/01/19 Python
python 实现红包随机生成算法的简单实例
2017/01/04 Python
python按综合、销量排序抓取100页的淘宝商品列表信息
2018/02/24 Python
解决python爬虫中有中文的url问题
2018/05/11 Python
Python实现将Excel转换成为image的方法
2018/10/23 Python
在PyCharm下打包*.py程序成.exe的方法
2018/11/29 Python
Python实现将多个空格换为一个空格.md的方法
2018/12/20 Python
django query模块
2019/04/20 Python
图解Python中深浅copy(通俗易懂)
2020/09/03 Python
CSS3悬停效果案例应用
2012/11/21 HTML / CSS
美国宠物用品网站:Value Pet Supplies
2018/03/17 全球购物
BASIC HOUSE官方旗舰店:韩国著名的服装品牌
2018/09/27 全球购物
是否有自动比较结构的方法
2015/06/03 面试题
写出一个方法实现冒泡排序
2016/07/08 面试题
读书小明星事迹材料
2014/05/03 职场文书
公司贷款承诺书
2014/05/30 职场文书
母亲节寄语大全
2015/02/27 职场文书
2015年护理工作总结范文
2015/04/03 职场文书
《梅花魂》教学反思
2016/02/18 职场文书