网络编程
位置:首页>> 网络编程>> Python编程>> python3+PyQt5实现柱状图

python3+PyQt5实现柱状图

作者:basisworker  发布时间:2023-06-02 22:19:36 

标签:python3,PyQt5,柱状图

本文通过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实现柱状图

来源:https://blog.csdn.net/xiaoyangyang20/article/details/70568656

0
投稿

猜你喜欢

手机版 网络编程 asp之家 www.aspxhome.com