python 3+PyQt 5 막대 그래프 구현
#!/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_()
실행 결과:이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Jupyter 공식 DockerHub에 대한 메모에 기재되어 있다. base-notebook minimal-notebook scipy-notebook tensorflow-notebook datascience-notebook pyspark-notebook all-s...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.