当前位置: 首页 > news >正文

Qt小组件 - 7 SQL Thread Qt访问数据库ORM

简介

网上关于Qt访问数据库的资料大多使用QSqlDatabase模块。虽然这在C++中尚可接受,但在Python中使用就显得过于繁琐了——不仅要手动编写SQL语句,还与Python追求简洁的理念背道而驰。

在这里写一个基于sqlalchemy的示例,也可以使用其他的ORM

sql_thread.py

# coding: utf-8
from collections import deque
from typing import Callablefrom PySide6.QtCore import QObject, Signal, QThread
from sqlalchemy.orm import Sessionclass SqlRequest:""" Sql request """def __init__(self, func: Callable, slot: Callable = None, params: dict = None):self.func = funcself.slot = slotself.params = params or {}class SqlResponse:""" Sql的反应 """def __init__(self, data: object, slot: Callable = None):self.slot = slotself.data = dataclass SqlSignalBus(QObject):""" Sql信号总线 """fetchDataSig = Signal(SqlRequest)dataFetched = Signal(SqlResponse)sqlSignalBus = SqlSignalBus()def sqlRequest(func: Callable, slot=None, **params):""" 从数据库查询 SQL 数据 """request = SqlRequest(func, slot, params)sqlSignalBus.fetchDataSig.emit(request)class DatabaseThread(QThread):def __init__(self, parent=None):super().__init__(parent=parent)self.server = Noneself.tasks = deque()sqlSignalBus.fetchDataSig.connect(self.onFetchData)def run(self):func, args, kwargs = self.serverserver: Session = func(*args, **kwargs)while self.tasks:request: SqlRequest = self.tasks.popleft()result = request.func(**request.params, server=server)sqlSignalBus.dataFetched.emit(SqlResponse(result, request.slot))server.close()def setServer(self, func: Callable, *args, **kwargs):self.server = (func, args, kwargs)def onFetchData(self, request: SqlRequest):self.tasks.append(request)if not self.isRunning():self.start()

db.py

# coding: utf-8
from random import randint, choicefrom sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, Sessionengine = create_engine('sqlite:///test.db')
Base = declarative_base()def create_session():return sessionmaker(bind=engine)()def init_create_table() -> None:Base.metadata.create_all(bind=engine, checkfirst=True)class User(Base):# 表的名字:__tablename__ = 'user'# 表的结构:id = Column(Integer, autoincrement=True, primary_key=True, comment='用户ID')name = Column(String(20))age = Column(Integer)phone = Column(String(20))email = Column(String(50))sex = Column(String(10))def __repr__(self):return f"User(id={self.id}, name={self.name}, age={self.age}, phone={self.phone}, email={self.email}, sex={self.sex})"def add_user(server: Session):server.add(User(name=f'Tom-{randint(1, 100)}', age=randint(1, 100), phone=str(randint(10000000, 99999999)),email='tom@123.com',sex=choice(['male', 'female'])))server.commit()def select_user(server: Session):users = server.query(User).all()return users

demo.py

# coding: utf-8
import sysfrom PySide6.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayoutfrom db import create_session, User, add_user, select_user, init_create_table
from sql_thread import sqlSignalBus, SqlResponse, DatabaseThread, sqlRequestclass MainWindow(QWidget):def __init__(self):super().__init__()self.setWindowTitle("Sql Thread Example")self.horizontalLayout = QHBoxLayout(self)self.addUserButton = QPushButton("Add User", self)self.selectUserButton = QPushButton("Select User", self)self.horizontalLayout.addWidget(self.addUserButton)self.horizontalLayout.addWidget(self.selectUserButton)self.resize(400, 300)self.databaseThread = DatabaseThread(self)self.databaseThread.setServer(create_session)sqlSignalBus.dataFetched.connect(self.onDataFetched)self.addUserButton.clicked.connect(lambda: sqlRequest(add_user))self.selectUserButton.clicked.connect(lambda: sqlRequest(select_user, self.onSelectUser))def onSelectUser(self, users: list[User]):print(users)def onDataFetched(self, response: SqlResponse):if response.slot:response.slot(response.data)if __name__ == '__main__':app = QApplication(sys.argv)init_create_table()mainWindow = MainWindow()mainWindow.show()sys.exit(app.exec())

在这里插入图片描述

http://www.dtcms.com/a/282349.html

相关文章:

  • gin go-kratos go-zero框架对比
  • 【后端】配置SqlSugar ORM框架并添加仓储
  • 【论文阅读 | IF 2025 | COMO:用于多模态目标检测的跨 Mamba 交互与偏移引导融合】
  • Web3.0与元宇宙:重构数字文明的技术范式与社会变革
  • 以太网供电与自愈网络对音视频系统的益处
  • 基于 elements3 包装的 可展开 table 组件
  • Elasticsearch+Logstash+Filebeat+Kibana部署
  • 前端状态管理对比:Redux与Vuex的深度分析
  • 利用 Spring 的 `@Scheduled` 注解结合简单的状态跟踪实现空闲检测方案
  • Node.js Domain 模块深度解析与最佳实践
  • 玩转Docker | 使用Docker部署vnStat网络流量监控服务
  • WPF 导入自定义字体并实现按钮悬停高亮效果
  • 微软AutoGen:多智能体协作的工业级解决方案
  • PostGres超过最大连接数报错
  • Linux LVS集群技术详解与实战指南
  • 通信算法之292:大疆DJI云哨系统-DroneID物理层协议解析-O1/O2/O3/O4机型都可以CRC正确
  • Redisson
  • 【知识图谱】Neo4j桌面版运行不起来怎么办?Neo4j Desktop无法打开!
  • C++设计模式之创建型模式
  • Qt小组件 - 6 异步运行函数
  • 暑假---作业2
  • QT技巧之快速搭建串口收发平台
  • Qt中实现文件(文本文件)内容对比
  • Django基础(三)———模板
  • Python设计模式深度解析:装饰器模式(Decorator Pattern)完全指南
  • hadoop 集群问题处理
  • 肠道宏基因组数据分析流程
  • 肠道宏基因组数据分析流程要关注的参数和指标
  • STM32-RTC内部时钟
  • 图像质量评价(Image Quality Assessment,IQA)