python3+PyQt5使用数据库表视图

这篇文章主要为大家详细介绍了python3+pyqt5使用数据库表视图,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

上文提到窗体可以一次性呈现出来自同一记录的各个域,但是对于用户希望能看到多条记录的表来说,就需要使用表格化的视图了。本文通过python3+pyqt5改写实现了python Qt gui 快速变成15章的例子,用户能够一次看到多条记录。

#!/usr/bin/env python3import osimport sysfrom PyQt5.QtCore import (PYQT_VERSION_STR, QDate, QFile, QRegExp, QVariant, QModelIndex,Qt)from PyQt5.QtWidgets import (QApplication,QComboBox,        QDateTimeEdit, QDialog, QGridLayout, QHBoxLayout, QLabel,        QLineEdit, QDateEdit,QMessageBox, QPushButton,        QStyleOptionViewItem, QTableView,QVBoxLayout)from PyQt5.QtGui import QPixmap,QCursor,QRegExpValidatorfrom PyQt5.QtSql import (QSqlDatabase, QSqlQuery, QSqlRelation,       QSqlRelationalDelegate, QSqlRelationalTableModel,QSqlTableModel)import qrc_resourcesMAC = Truetry: from PyQt5.QtGui import qt_mac_set_native_menubarexcept ImportError: MAC = FalseID = 0NAME = ASSETID = 1CATEGORYID = DATE = DESCRIPTION = 2ROOM = ACTIONID = 3ACQUIRED = 1def createFakeData(): import random print("Dropping tables...") query = QSqlQuery() query.exec_("DROP TABLE assets") query.exec_("DROP TABLE logs") query.exec_("DROP TABLE actions") query.exec_("DROP TABLE categories") QApplication.processEvents() print("Creating tables...") query.exec_("""CREATE TABLE actions (    id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,    name VARCHAR(20) NOT NULL,    description VARCHAR(40) NOT NULL)""") query.exec_("""CREATE TABLE categories (    id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,    name VARCHAR(20) NOT NULL,    description VARCHAR(40) NOT NULL)""") query.exec_("""CREATE TABLE assets (    id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,    name VARCHAR(40) NOT NULL,    categoryid INTEGER NOT NULL,    room VARCHAR(4) NOT NULL,    FOREIGN KEY (categoryid) REFERENCES categories)""") query.exec_("""CREATE TABLE logs (    id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,    assetid INTEGER NOT NULL,    date DATE NOT NULL,    actionid INTEGER NOT NULL,    FOREIGN KEY (assetid) REFERENCES assets,    FOREIGN KEY (actionid) REFERENCES actions)""") QApplication.processEvents() print("Populating tables...") query.exec_("INSERT INTO actions (name, description) "    "VALUES ('Acquired', 'When installed')") query.exec_("INSERT INTO actions (name, description) "    "VALUES ('Broken', 'When failed and unusable')") query.exec_("INSERT INTO actions (name, description) "    "VALUES ('Repaired', 'When back in service')") query.exec_("INSERT INTO actions (name, description) "    "VALUES ('Routine maintenance', "    "'When tested, refilled, etc.')") query.exec_("INSERT INTO categories (name, description) VALUES "    "('Computer Equipment', "    "'Monitors, System Units, Peripherals, etc.')") query.exec_("INSERT INTO categories (name, description) VALUES "    "('Furniture', 'Chairs, Tables, Desks, etc.')") query.exec_("INSERT INTO categories (name, description) VALUES "    "('Electrical Equipment', 'Non-computer electricals')") today = QDate.currentDate() floors = list(range(1, 12)) + list(range(14, 28)) monitors = (('17" LCD Monitor', 1),    ('20" LCD Monitor', 1),    ('21" LCD Monitor', 1),    ('21" CRT Monitor', 1),    ('24" CRT Monitor', 1)) computers = (("Computer (32-bit/80GB/0.5GB)", 1),     ("Computer (32-bit/100GB/1GB)", 1),     ("Computer (32-bit/120GB/1GB)", 1),     ("Computer (64-bit/240GB/2GB)", 1),     ("Computer (64-bit/320GB/4GB)", 1)) printers = (("Laser Printer (4 ppm)", 1),    ("Laser Printer (6 ppm)", 1),    ("Laser Printer (8 ppm)", 1),    ("Laser Printer (16 ppm)", 1)) chairs = (("Secretary Chair", 2),    ("Executive Chair (Basic)", 2),    ("Executive Chair (Ergonimic)", 2),    ("Executive Chair (Hi-Tech)", 2)) desks = (("Desk (Basic, 3 drawer)", 2),    ("Desk (Standard, 3 drawer)", 2),    ("Desk (Executive, 3 drawer)", 2),    ("Desk (Executive, 4 drawer)", 2),    ("Desk (Large, 4 drawer)", 2)) furniture = (("Filing Cabinet (3 drawer)", 2),     ("Filing Cabinet (4 drawer)", 2),     ("Filing Cabinet (5 drawer)", 2),     ("Bookcase (4 shelves)", 2),     ("Bookcase (6 shelves)", 2),     ("Table (4 seater)", 2),     ("Table (8 seater)", 2),     ("Table (12 seater)", 2)) electrical = (("Fan (3 speed)", 3),     ("Fan (5 speed)", 3),     ("Photocopier (4 ppm)", 3),     ("Photocopier (6 ppm)", 3),     ("Photocopier (8 ppm)", 3),     ("Shredder", 3)) query.prepare("INSERT INTO assets (name, categoryid, room) "     "VALUES (:name, :categoryid, :room)") logQuery = QSqlQuery() logQuery.prepare("INSERT INTO logs (assetid, date, actionid) "      "VALUES (:assetid, :date, :actionid)") assetid = 1 for i in range(20):  room = "{0:02d}{1:02d}".format(    random.choice(floors), random.randint(1, 62))  for name, category in (random.choice(monitors),    random.choice(computers), random.choice(chairs),    random.choice(desks), random.choice(furniture)):   query.bindValue(":name", name)   query.bindValue(":categoryid", category)   query.bindValue(":room", room)   query.exec_()   logQuery.bindValue(":assetid", assetid)   when = today.addDays(-random.randint(7, 1500))   #when=when.toString()   logQuery.bindValue(":date", when.toString("yyyy-MM-dd"))   logQuery.bindValue(":actionid", ACQUIRED)   logQuery.exec_()   if random.random() > 0.7:    logQuery.bindValue(":assetid", assetid)    when = when.addDays(random.randint(1, 1500))    if when  0.8:   name, category = random.choice(printers)   query.bindValue(":name", name)   query.bindValue(":categoryid", category)   query.bindValue(":room", room)   query.exec_()   logQuery.bindValue(":assetid", assetid)   when = today.addDays(-random.randint(7, 1500))   logQuery.bindValue(":date", when.toString("yyyy-MM-dd"))   logQuery.bindValue(":actionid",ACQUIRED)   logQuery.exec_()   if random.random() > 0.6:    logQuery.bindValue(":assetid", assetid)    when = when.addDays(random.randint(1, 1500))    if when  0.6:   name, category = random.choice(electrical)   query.bindValue(":name", name)   query.bindValue(":categoryid", category)   query.bindValue(":room", room)   query.exec_()   logQuery.bindValue(":assetid", assetid)   when = today.addDays(-random.randint(7, 1500))   logQuery.bindValue(":date", when.toString("yyyy-MM-dd"))   logQuery.bindValue(":actionid",ACQUIRED)   logQuery.exec_()   if random.random() > 0.5:    logQuery.bindValue(":assetid", assetid)    when = when.addDays(random.randint(1, 1500))    if when "        "from the {1} table because it is used by "        "{2} records").format(record.value(NAME),table,count))   #QSqlDatabase.database().rollback()   return  self.model.removeRow(index.row())  self.model.submitAll()  self.model.select()  #QSqlDatabase.database().commit()class AssetDelegate(QSqlRelationalDelegate): def __init__(self, parent=None):  super(AssetDelegate, self).__init__(parent) def paint(self, painter, option, index):  myoption = QStyleOptionViewItem(option)  if index.column() == ROOM:   myoption.displayAlignment |= (Qt.AlignRight|Qt.AlignVCenter)  QSqlRelationalDelegate.paint(self, painter, myoption, index) def createEditor(self, parent, option, index):  if index.column() == ROOM:   editor = QLineEdit(parent)   regex = QRegExp(r"(?:0[1-9]|1[0124-9]|2[0-7])"         r"(?:0[1-9]|[1-5][0-9]|6[012])")   validator = QRegExpValidator(regex, parent)   editor.setValidator(validator)   editor.setInputMask("9999")   editor.setAlignment(Qt.AlignRight|Qt.AlignVCenter)   return editor  else:   return QSqlRelationalDelegate.createEditor(self, parent,              option, index) def setEditorData(self, editor, index):  if index.column() == ROOM:   text = index.model().data(index, Qt.DisplayRole)   editor.setText(text)  else:   QSqlRelationalDelegate.setEditorData(self, editor, index) def setModelData(self, editor, model, index):  if index.column() == ROOM:   model.setData(index, editor.text())  else:   QSqlRelationalDelegate.setModelData(self, editor, model,            index)class LogDelegate(QSqlRelationalDelegate): def __init__(self, parent=None):  super(LogDelegate, self).__init__(parent) def paint(self, painter, option, index):  myoption = QStyleOptionViewItem(option)  if index.column() == DATE:   myoption.displayAlignment |= (Qt.AlignRight|Qt.AlignVCenter)  QSqlRelationalDelegate.paint(self, painter, myoption, index) def createEditor(self, parent, option, index):  if (index.column() == ACTIONID and   index.model().data(index, Qt.DisplayRole) ==   ACQUIRED): # Acquired is read-only   return  if index.column() == DATE:   editor = QDateEdit(parent)   editor.setMaximumDate(QDate.currentDate())   editor.setDisplayFormat("yyyy-MM-dd")   if PYQT_VERSION_STR >= "4.1.0":    editor.setCalendarPopup(True)   editor.setAlignment(Qt.AlignRight|        Qt.AlignVCenter)   return editor  else:   return QSqlRelationalDelegate.createEditor(self, parent,              option, index) def setEditorData(self, editor, index):  if index.column() == DATE:   date = index.model().data(index, Qt.DisplayRole)   editor.setDate(date)  else:   QSqlRelationalDelegate.setEditorData(self, editor, index) def setModelData(self, editor, model, index):  if index.column() == DATE:   model.setData(index, QVariant(editor.date()))  else:   QSqlRelationalDelegate.setModelData(self, editor, model,            index)class MainForm(QDialog): def __init__(self):  super(MainForm, self).__init__()  self.assetModel = QSqlRelationalTableModel(self)  self.assetModel.setTable("assets")  self.assetModel.setRelation(CATEGORYID,    QSqlRelation("categories", "id", "name"))  self.assetModel.setSort(ROOM, Qt.AscendingOrder)  self.assetModel.setHeaderData(ID, Qt.Horizontal,"ID")  self.assetModel.setHeaderData(NAME, Qt.Horizontal,"Name")  self.assetModel.setHeaderData(CATEGORYID, Qt.Horizontal,"Category")  self.assetModel.setHeaderData(ROOM, Qt.Horizontal,"Room")  self.assetModel.select()  self.assetView = QTableView()  self.assetView.setModel(self.assetModel)  self.assetView.setItemDelegate(AssetDelegate(self))  self.assetView.setSelectionMode(QTableView.SingleSelection)  self.assetView.setSelectionBehavior(QTableView.SelectRows)  self.assetView.setColumnHidden(ID, True)  self.assetView.resizeColumnsToContents()  assetLabel = QLabel("A&ssets")  assetLabel.setBuddy(self.assetView)  self.logModel = QSqlRelationalTableModel(self)  self.logModel.setTable("logs")  self.logModel.setRelation(ACTIONID,    QSqlRelation("actions", "id", "name"))  self.logModel.setSort(DATE, Qt.AscendingOrder)  self.logModel.setHeaderData(DATE, Qt.Horizontal, "Date")  self.logModel.setHeaderData(ACTIONID, Qt.Horizontal,"Action")  self.logModel.select()  self.logView = QTableView()  self.logView.setModel(self.logModel)  self.logView.setItemDelegate(LogDelegate(self))  self.logView.setSelectionMode(QTableView.SingleSelection)  self.logView.setSelectionBehavior(QTableView.SelectRows)  self.logView.setColumnHidden(ID, True)  self.logView.setColumnHidden(ASSETID, True)  self.logView.resizeColumnsToContents()  self.logView.horizontalHeader().setStretchLastSection(True)  logLabel = QLabel("&Logs")  logLabel.setBuddy(self.logView)  addAssetButton = QPushButton("&Add Asset")  deleteAssetButton = QPushButton("&Delete Asset")  addActionButton = QPushButton("Add A&ction")  deleteActionButton = QPushButton("Delete Ac&tion")  editActionsButton = QPushButton("&Edit Actions...")  editCategoriesButton = QPushButton("Ed&it Categories...")  quitButton = QPushButton("&Quit")  for button in (addAssetButton, deleteAssetButton,    addActionButton, deleteActionButton,    editActionsButton, editCategoriesButton, quitButton):   if MAC:    button.setDefault(False)    button.setAutoDefault(False)   else:    button.setFocusPolicy(Qt.NoFocus)  dataLayout = QVBoxLayout()  dataLayout.addWidget(assetLabel)  dataLayout.addWidget(self.assetView, 1)  dataLayout.addWidget(logLabel)  dataLayout.addWidget(self.logView)  buttonLayout = QVBoxLayout()  buttonLayout.addWidget(addAssetButton)  buttonLayout.addWidget(deleteAssetButton)  buttonLayout.addWidget(addActionButton)  buttonLayout.addWidget(deleteActionButton)  buttonLayout.addWidget(editActionsButton)  buttonLayout.addWidget(editCategoriesButton)  buttonLayout.addStretch()  buttonLayout.addWidget(quitButton)  layout = QHBoxLayout()  layout.addLayout(dataLayout, 1)  layout.addLayout(buttonLayout)  self.setLayout(layout)  #self.connect(self.assetView.selectionModel(),    #SIGNAL(("currentRowChanged(QModelIndex,QModelIndex)")),    #self.assetChanged)  self.assetView.selectionModel().currentRowChanged.connect(self.assetChanged)  addAssetButton.clicked.connect(self.addAsset)  deleteAssetButton.clicked.connect(self.deleteAsset)  addActionButton.clicked.connect(self.addAction)  deleteActionButton.clicked.connect(self.deleteAction)  editActionsButton.clicked.connect(self.editActions)  editCategoriesButton.clicked.connect(self.editCategories)  quitButton.clicked.connect(self.done)  self.assetChanged(self.assetView.currentIndex())  self.setMinimumWidth(650)  self.setWindowTitle("Asset Manager") def done(self, result=1):  query = QSqlQuery()  query.exec_("DELETE FROM logs WHERE logs.assetid NOT IN"     "(SELECT id FROM assets)")  QDialog.done(self, 1) def assetChanged(self, index):  if index.isValid():   record = self.assetModel.record(index.row())   #print(index.row())   id = record.value("id")   self.logModel.setFilter("assetid = {0}".format(id))  else:   self.logModel.setFilter("assetid = -1")  #self.logModel.reset() # workaround for Qt  0)  if PYQT_VERSION_STR Delete
{0}"        "
from room {1}").format(record.value(NAME),record.value(ROOM))  if logrecords > 1:   msg += (", along with {0} log records"     .format(logrecords))  msg += "?"  if (QMessageBox.question(self, "Delete Asset", msg,    QMessageBox.Yes|QMessageBox.No) ==    QMessageBox.No):   QSqlDatabase.database().rollback()   return  #query.exec_("DELETE FROM logs WHERE assetid = {0}"  #    .format(assetid))  #use model API  self.logModel.setFilter("assetid={0}".format(assetid))  self.logModel.select()  if self.logModel.rowCount()>0:   self.logModel.removeRows(0,self.logModel.rowCount())   self.logModel.submitAll()     self.assetModel.removeRow(index.row())  self.assetModel.submitAll()  QSqlDatabase.database().commit()  self.assetModel.select()  self.assetChanged(self.assetView.currentIndex()) def addAction(self):  index = self.assetView.currentIndex()  if not index.isValid():   return  QSqlDatabase.database().transaction()  record = self.assetModel.record(index.row())  assetid = record.value(ID)  row = self.logModel.rowCount()  self.logModel.insertRow(row)  self.logModel.setData(self.logModel.index(row, ASSETID),        assetid)  self.logModel.setData(self.logModel.index(row, DATE),        QDate.currentDate())  QSqlDatabase.database().commit()  index = self.logModel.index(row, ACTIONID)  self.logView.setCurrentIndex(index)  self.logView.edit(index) def deleteAction(self):  index = self.logView.currentIndex()  if not index.isValid():   return  record = self.logModel.record(index.row())  action = record.value(ACTIONID)  if action == "Acquired":   QMessageBox.information(self, "Delete Log",     "The 'Acquired' log record cannot be deleted.
"     "You could delete the entire asset instead.")   return  when = str(record.value(DATE))  if (QMessageBox.question(self, "Delete Log",    "Delete log
{0} {1}?".format(when, action),    QMessageBox.Yes|QMessageBox.No) ==    QMessageBox.No):   return  self.logModel.removeRow(index.row())  self.logModel.submitAll()  self.logModel.select() def editActions(self):  form = ReferenceDataDlg("actions", "Action", self)  form.exec_() def editCategories(self):  form = ReferenceDataDlg("categories", "Category", self)  form.exec_()def main(): app = QApplication(sys.argv) filename = os.path.join(os.path.dirname(__file__), "assets.db") create = not QFile.exists(filename) db = QSqlDatabase.addDatabase("QSQLITE") db.setDatabaseName(filename) if not db.open():  QMessageBox.warning(None, "Asset Manager",   ("Database Error: {0}"   .format(db.lastError().text())))  sys.exit(1) splash = None if create:  app.setOverrideCursor(QCursor(Qt.WaitCursor))  splash = QLabel()  pixmap = QPixmap(":/assetmanagersplash.png")  splash.setPixmap(pixmap)  splash.setMask(pixmap.createHeuristicMask())  splash.setWindowFlags(Qt.SplashScreen)  rect = app.desktop().availableGeometry()  splash.move((rect.width() - pixmap.width()) / 2,     (rect.height() - pixmap.height()) / 2)  splash.show()  app.processEvents()  createFakeData() form = MainForm() form.show() if create:  splash.close()  app.processEvents()  app.restoreOverrideCursor() app.exec_() del form del dbmain()

登录后复制

运行结果:

python3+PyQt5使用数据库表视图

相关推荐:

立即学习“Python免费学习笔记(深入)”;

python3+PyQt5实现拖放功能

python3+PyQt5自定义视图详解

python3+PyQt5泛型委托详解

以上就是python3+PyQt5使用数据库表视图的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2263367.html

(0)
上一篇 2025年2月27日 07:33:27
下一篇 2025年2月27日 07:33:42

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • vue.js怎么连接数据库

    vue.js连接数据库的方法:1、建立php站点;2、创建数据库;3、php连接数据库;4、创建vue站点;5、创建组件,连接数据库;6、加载组件;7、在app.vue中引入组件。 本文操作环境:windows10系统、php 7&…

    2025年4月5日 编程技术
    200
  • 如何使用Swoole实现WebSocket服务器与数据库交互

    如何使用Swoole实现WebSocket服务器与数据库交互 简介:WebSocket是一种基于TCP协议的全双工通信协议,可以在客户端与服务器之间建立实时的双向通信。而Swoole是一款PHP扩展,可以方便地实现高性能的异步、并发编程。在…

    2025年4月2日
    100
  • Swoole实战:如何使用协程进行数据库操作

    Swoole 实战:如何使用协程进行数据库操作 引言 随着互联网的发展,大量的数据需要存储和处理。对于开发人员来说,在高并发场景下进行数据库操作是一个常见的需求。传统的数据库操作方式会面临阻塞、性能瓶颈等问题,而协程则成为了解决这些问题的一…

    2025年4月2日
    100
  • phonegap使用方法介绍(八)操作数据库

    下面小编就为大家带来一篇使用phonegap操作数据库的实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧 实例如下: nbsp;html>                          Dat…

    编程技术 2025年4月1日
    300
  • H5的本地存储和本地数据库详细介绍

    这次给大家带来h5的本地存储和本地数据库详细介绍,使用h5的本地存储和本地数据库的本地数据库有哪些,下面就是实战案例,一起来看一下。 本地存储 1.1 本地存储由来的背景 由于HTML4时代Cookie的大小、格式、存储数据格式等限制,网站…

    编程技术 2025年4月1日
    100
  • 使用Ajax和Jquery实现下拉框的二级联动

    下面我就为大家分享一篇使用ajax和jquery配合数据库实现下拉框的二级联动的示例,具有很好的参考价值,希望对大家有所帮助。 首先我们需要先建立好数据库,将一些数据插入进去 需要两张表: province:省份表 city: 城市表 如图…

    2025年3月31日 编程技术
    100
  • 通过javascript连接任意数据库

    下面我就为大家分享一篇javascript连接mysql与php通过odbc连接任意数据库的实例,具有很好的参考价值,希望对大家有所帮助 脑洞大开用javascript链接mysql,2个小时总算实现了,用到了odbc,后面又想到用php链…

    2025年3月31日
    100
  • 如何在Linux上配置分布式数据库

    如何在linux上配置分布式数据库 随着数据量和数据需求的增加,传统的单节点数据库已经无法满足现代应用的需求。分布式数据库的出现为海量数据的管理和查询提供了一种解决方案。本文将重点介绍如何在linux上配置分布式数据库,并提供一些经典的代码…

    编程技术 2025年3月30日
    100
  • php如何使用CakePHP框架?

    在现代web开发中,使用mvc框架能够大大提高开发效率和代码可维护性。cakephp是一款基于mvc设计模式的php框架,其易用性和灵活性使得它受到了许多开发者的喜爱。在这篇文章中,我们将介绍如何使用cakephp框架来开发web应用程序。…

    编程技术 2025年3月30日
    100
  • MySQL数据行溢出的深入理解

    本篇文章给大家带来的内容是关于mysql数据行溢出的深入理解,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 一、从常见的报错说起 故事的开头我们先来看一个常见的sql报错信息: 相信对于这类报错大家一定遇到过很多次了,特别…

    2025年3月30日 编程技术
    100

发表回复

登录后才能评论