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生成器的使用方法
Nov 21 Python
Linux环境下MySQL-python安装过程分享
Feb 02 Python
python通过定义一个类实例作为ftp回调方法
May 04 Python
Python导入oracle数据的方法
Jul 10 Python
Python中数字以及算数运算符的相关使用
Oct 12 Python
Python实现完整的事务操作示例
Jun 20 Python
python+pyqt实现12306图片验证效果
Oct 25 Python
Python序列循环移位的3种方法推荐
Apr 09 Python
python程序 创建多线程过程详解
Sep 23 Python
python 实现屏幕录制示例
Dec 23 Python
golang/python实现归并排序实例代码
Aug 30 Python
python 单机五子棋对战游戏
Apr 28 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扩展开发经验分享
2012/09/06 PHP
PHP中设置时区,记录日志文件的实现代码
2013/01/07 PHP
解析PHP生成静态html文件的三种方法
2013/06/18 PHP
提高PHP编程效率的方法
2013/11/07 PHP
php指定函数参数默认值示例代码
2013/12/04 PHP
PHP中读取文件的8种方法和代码实例
2014/08/05 PHP
php编译安装php-amq扩展简明教程
2016/06/25 PHP
centos 7.2下搭建LNMP环境教程
2016/11/20 PHP
利用Homestead快速运行一个Laravel项目的方法详解
2017/11/14 PHP
PHP获取ttf格式文件字体名的方法示例
2019/03/06 PHP
js实现图片从左往右渐变切换效果的方法
2015/02/06 Javascript
深入理解JavaScript系列(47):对象创建模式(上篇)
2015/03/04 Javascript
jQuery实现在列表的首行添加数据
2015/05/19 Javascript
JS使用正则表达式过滤多个词语并替换为相同长度星号的方法
2016/08/03 Javascript
AngularJS过滤器详解及示例代码
2016/08/16 Javascript
JavaScript中的call和apply的用途以及区别
2017/01/11 Javascript
JS字符串去除连续或全部重复字符的实例
2018/03/08 Javascript
JavaScript数组方法的错误使用例子
2018/09/13 Javascript
详解Vue中组件的缓存
2019/04/20 Javascript
Angular.JS读取数据库数据调用完整实例
2019/07/02 Javascript
JS插入排序简单理解与实现方法分析
2019/11/25 Javascript
python自动化生成IOS的图标
2018/11/13 Python
Django Python 获取请求头信息Content-Range的方法
2019/08/06 Python
解决python DataFrame 打印结果不换行问题
2020/04/09 Python
基于python实现检索标记敏感词并输出
2020/05/07 Python
Python函数__new__及__init__作用及区别解析
2020/08/31 Python
django使用graphql的实例
2020/09/02 Python
中国跨境海淘网站:考拉海购
2016/08/01 全球购物
山海经纬软件测试笔试题和面试题
2013/04/02 面试题
就业推荐自我鉴定
2013/10/06 职场文书
求职信的最佳写作思路
2014/02/01 职场文书
网管求职信
2014/03/03 职场文书
大专生自荐书范文
2014/06/22 职场文书
党的群众路线教育实践活动党员个人整改措施
2014/10/27 职场文书
2014年档案室工作总结
2014/12/01 职场文书
2016年度师德标兵先进事迹材料
2016/02/26 职场文书