我是靠谱客的博主 碧蓝火,最近开发中收集的这篇文章主要介绍pyqt5 python3.7教程_python3+PyQt5自定义视图详解,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

这篇文章主要为大家详细介绍了python3+PyQt5自定义视图的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

pyqt提供的几个视图类都可以较好工作,包括QLisView,QTableView和QTreeView。但是对于一些难以用现有的方式来呈现数据,这时,可以创建我们自己的视图子类并将其用做模型数据的可视化来解决这一问题。本文通过Python3+pyqt5实现了python Qt GUI 快速编程的16章的例子。

#!/usr/bin/env python3

import gzip

import os

import platform

import sys

from PyQt5.QtCore import (QAbstractTableModel, QDateTime, QModelIndex,

QSize, QTimer, QVariant, Qt,pyqtSignal)

from PyQt5.QtGui import ( QColor, QCursor, QFont,

QFontDatabase, QFontMetrics, QPainter, QPalette, QPixmap)

from PyQt5.QtWidgets import QApplication,QDialog,QHBoxLayout, QLabel, QMessageBox,QScrollArea, QSplitter, QTableView,QWidget

(TIMESTAMP, TEMPERATURE, INLETFLOW, TURBIDITY, CONDUCTIVITY,

COAGULATION, RAWPH, FLOCCULATEDPH) = range(8)

TIMESTAMPFORMAT = "yyyy-MM-dd hh:mm"

class WaterQualityModel(QAbstractTableModel):

def __init__(self, filename):

super(WaterQualityModel, self).__init__()

self.filename = filename

self.results = []

def load(self):

self.beginResetModel()

exception = None

fh = None

try:

if not self.filename:

raise IOError("no filename specified for loading")

self.results = []

line_data = gzip.open(self.filename).read()

for line in line_data.decode("utf8").splitlines():

parts = line.rstrip().split(",")

date = QDateTime.fromString(parts[0] + ":00",

Qt.ISODate)

result = [date]

for part in parts[1:]:

result.append(float(part))

self.results.append(result)

except (IOError, ValueError) as e:

exception = e

finally:

if fh is not None:

fh.close()

self.endResetModel()

if exception is not None:

raise exception

def data(self, index, role=Qt.DisplayRole):

if (not index.isValid() or

not (0 <= index.row() < len(self.results))):

return QVariant()

column = index.column()

result = self.results[index.row()]

if role == Qt.DisplayRole:

item = result[column]

if column == TIMESTAMP:

#item = item.toString(TIMESTAMPFORMAT)

item=item

else:

#item = QString("%1").arg(item, 0, "f", 2)

item = "{0:.2f}".format(item)

return item

elif role == Qt.TextAlignmentRole:

if column != TIMESTAMP:

return QVariant(int(Qt.AlignRight|Qt.AlignVCenter))

return QVariant(int(Qt.AlignLeft|Qt.AlignVCenter))

elif role == Qt.TextColorRole and column == INLETFLOW:

if result[column] < 0:

return QVariant(QColor(Qt.red))

elif (role == Qt.TextColorRole and

column in (RAWPH, FLOCCULATEDPH)):

ph = result[column]

if ph < 7:

return QVariant(QColor(Qt.red))

elif ph >= 8:

return QVariant(QColor(Qt.blue))

else:

return QVariant(QColor(Qt.darkGreen))

return QVariant()

def headerData(self, section, orientation, role=Qt.DisplayRole):

if role == Qt.TextAlignmentRole:

if orientation == Qt.Horizontal:

return QVariant(int(Qt.AlignCenter))

return QVariant(int(Qt.AlignRight|Qt.AlignVCenter))

if role != Qt.DisplayRole:

return QVariant()

if orientation == Qt.Horizontal:

if section == TIMESTAMP:

return "Timestamp"

elif section == TEMPERATURE:

return "u00B0" +"C"

elif section == INLETFLOW:

return "Inflow"

elif section == TURBIDITY:

return "NTU"

elif section == CONDUCTIVITY:

return "u03BCS/cm"

elif section == COAGULATION:

return "mg/L"

elif section == RAWPH:

return "Raw Ph"

elif section == FLOCCULATEDPH:

return "Floc Ph"

return int(section + 1)

def rowCount(self, index=QModelIndex()):

return len(self.results)

def columnCount(self, index=QModelIndex()):

return 8

class WaterQualityView(QWidget):

clicked = pyqtSignal(QModelIndex)

FLOWCHARS = (chr(0x21DC), chr(0x21DD), chr(0x21C9))

def __init__(self, parent=None):

super(WaterQualityView, self).__init__(parent)

self.scrollarea = None

self.model = None

self.setFocusPolicy(Qt.StrongFocus)

self.selectedRow = -1

self.flowfont = self.font()

size = self.font().pointSize()

if platform.system() == "Windows":

fontDb = QFontDatabase()

for face in [face.toLower() for face in fontDb.families()]:

if face.contains("unicode"):

self.flowfont = QFont(face, size)

break

else:

self.flowfont = QFont("symbol", size)

WaterQualityView.FLOWCHARS = (chr(0xAC), chr(0xAE),

chr(0xDE))

def setModel(self, model):

self.model = model

#self.connect(self.model,

# SIGNAL("dataChanged(QModelIndex,QModelIndex)"),

# self.setNewSize)

self.model.dataChanged.connect(self.setNewSize)

#self.connect(self.model, SIGNAL("modelReset()"), self.setNewSize)

self.model.modelReset.connect(self.setNewSize)

self.setNewSize()

def setNewSize(self):

self.resize(self.sizeHint())

self.update()

self.updateGeometry()

def minimumSizeHint(self):

size = self.sizeHint()

fm = QFontMetrics(self.font())

size.setHeight(fm.height() * 3)

return size

def sizeHint(self):

fm = QFontMetrics(self.font())

size = fm.height()

return QSize(fm.width("9999-99-99 99:99 ") + (size * 4),

(size / 4) + (size * self.model.rowCount()))

def paintEvent(self, event):

if self.model is None:

return

fm = QFontMetrics(self.font())

timestampWidth = fm.width("9999-99-99 99:99 ")

size = fm.height()

indicatorSize = int(size * 0.8)

offset = int(1.5 * (size - indicatorSize))

minY = event.rect().y()

maxY = minY + event.rect().height() + size

minY -= size

painter = QPainter(self)

painter.setRenderHint(QPainter.Antialiasing)

painter.setRenderHint(QPainter.TextAntialiasing)

y = 0

for row in range(self.model.rowCount()):

x = 0

if minY <= y <= maxY:

painter.save()

painter.setPen(self.palette().color(QPalette.Text))

if row == self.selectedRow:

painter.fillRect(x, y + (offset * 0.8),

self.width(), size, self.palette().highlight())

painter.setPen(self.palette().color(

QPalette.HighlightedText))

#timestamp = self.model.data(

#self.model.index(row, TIMESTAMP)).toDateTime()

timestamp = self.model.data(self.model.index(row, TIMESTAMP))

painter.drawText(x, y + size,

timestamp.toString(TIMESTAMPFORMAT))

#print(timestamp.toString(TIMESTAMPFORMAT))

x += timestampWidth

temperature = self.model.data(

self.model.index(row, TEMPERATURE))

#temperature = temperature.toDouble()[0]

temperature = float(temperature)

if temperature < 20:

color = QColor(0, 0,

int(255 * (20 - temperature) / 20))

elif temperature > 25:

color = QColor(int(255 * temperature / 100), 0, 0)

else:

color = QColor(0, int(255 * temperature / 100), 0)

painter.setPen(Qt.NoPen)

painter.setBrush(color)

painter.drawEllipse(x, y + offset, indicatorSize,

indicatorSize)

x += size

rawPh = self.model.data(self.model.index(row, RAWPH))

#rawPh = rawPh.toDouble()[0]

rawPh = float(rawPh)

if rawPh < 7:

color = QColor(int(255 * rawPh / 10), 0, 0)

elif rawPh >= 8:

color = QColor(0, 0, int(255 * rawPh / 10))

else:

color = QColor(0, int(255 * rawPh / 10), 0)

painter.setBrush(color)

painter.drawEllipse(x, y + offset, indicatorSize,

indicatorSize)

x += size

flocPh = self.model.data(

self.model.index(row, FLOCCULATEDPH))

#flocPh = flocPh.toDouble()[0]

flocPh = float(flocPh)

if flocPh < 7:

color = QColor(int(255 * flocPh / 10), 0, 0)

elif flocPh >= 8:

color = QColor(0, 0, int(255 * flocPh / 10))

else:

color = QColor(0, int(255 * flocPh / 10), 0)

painter.setBrush(color)

painter.drawEllipse(x, y + offset, indicatorSize,

indicatorSize)

painter.restore()

painter.save()

x += size

flow = self.model.data(

self.model.index(row, INLETFLOW))

#flow = flow.toDouble()[0]

flow = float(flow)

char = None

if flow <= 0:

char = WaterQualityView.FLOWCHARS[0]

elif flow < 3.6:

char = WaterQualityView.FLOWCHARS[1]

elif flow > 4.7:

char = WaterQualityView.FLOWCHARS[2]

if char is not None:

painter.setFont(self.flowfont)

painter.drawText(x, y + size, char)

painter.restore()

y += size

if y > maxY:

break

def mousePressEvent(self, event):

fm = QFontMetrics(self.font())

self.selectedRow = event.y() // fm.height()

self.update()

#self.emit(SIGNAL("clicked(QModelIndex)"),

# self.model.index(self.selectedRow, 0))

self.clicked.emit(self.model.index(self.selectedRow, 0))

def keyPressEvent(self, event):

if self.model is None:

return

row = -1

if event.key() == Qt.Key_Up:

row = max(0, self.selectedRow - 1)

elif event.key() == Qt.Key_Down:

row = min(self.selectedRow + 1, self.model.rowCount() - 1)

if row != -1 and row != self.selectedRow:

self.selectedRow = row

if self.scrollarea is not None:

fm = QFontMetrics(self.font())

y = fm.height() * self.selectedRow

print(y)

self.scrollarea.ensureVisible(0, y)

self.update()

#self.emit(SIGNAL("clicked(QModelIndex)"),

# self.model.index(self.selectedRow, 0))

self.clicked.emit(self.model.index(self.selectedRow, 0))

else:

QWidget.keyPressEvent(self, event)

class MainForm(QDialog):

def __init__(self, parent=None):

super(MainForm, self).__init__(parent)

self.model = WaterQualityModel(os.path.join(

os.path.dirname(__file__), "waterdata.csv.gz"))

self.tableView = QTableView()

self.tableView.setAlternatingRowColors(True)

self.tableView.setModel(self.model)

self.waterView = WaterQualityView()

self.waterView.setModel(self.model)

scrollArea = QScrollArea()

scrollArea.setBackgroundRole(QPalette.Light)

scrollArea.setWidget(self.waterView)

self.waterView.scrollarea = scrollArea

splitter = QSplitter(Qt.Horizontal)

splitter.addWidget(self.tableView)

splitter.addWidget(scrollArea)

splitter.setSizes([600, 250])

layout = QHBoxLayout()

layout.addWidget(splitter)

self.setLayout(layout)

self.setWindowTitle("Water Quality Data")

QTimer.singleShot(0, self.initialLoad)

def initialLoad(self):

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

splash = QLabel(self)

pixmap = QPixmap(os.path.join(os.path.dirname(__file__),

"iss013-e-14802.jpg"))

#print(os.path.join(os.path.dirname(__file__),

# "iss013-e-14802.jpg"))

splash.setPixmap(pixmap)

splash.setWindowFlags(Qt.SplashScreen)

splash.move(self.x() + ((self.width() - pixmap.width()) / 2),

self.y() + ((self.height() - pixmap.height()) / 2))

splash.show()

QApplication.processEvents()

try:

self.model.load()

except IOError as e:

QMessageBox.warning(self, "Water Quality - Error", e)

else:

self.tableView.resizeColumnsToContents()

splash.close()

QApplication.processEvents()

QApplication.restoreOverrideCursor()

app = QApplication(sys.argv)

form = MainForm()

form.resize(850, 620)

form.show()

app.exec_()

运行结果:

e0d46aa9c8755cec095a04b9468cd100.png

相关推荐:

最后

以上就是碧蓝火为你收集整理的pyqt5 python3.7教程_python3+PyQt5自定义视图详解的全部内容,希望文章能够帮你解决pyqt5 python3.7教程_python3+PyQt5自定义视图详解所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(55)

评论列表共有 0 条评论

立即
投稿
返回
顶部