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

入门 PyQt6 看过来(项目)27 在线购物-商品选购

商品选购页面包含商品选购标题,商品搜索框和搜索按钮,用户信息,商品列表展示以及商品图片展示。如下图所示:

1 页面设计

我们根据上图展示在QTDesigner里设计如下:

商品选购、商品名称、用户、图片等文字用QLabel标签。查询和选购以及打印用QPushButton按钮。列表采用QTableView​列表视图。

其中他们的属性名字命名如下:

2 功能实现

2.1 查询功能

点击商品查询,输入内容或者空的时候,会在列表里展示查询到的商品信息。

    def query(self):global commodityspnm=self.lePNm.text()book=openpyxl.load_workbook(r'data/netshop.xlsx')sheet=book['商品表']commoditys=[]list_key=['商品号','商品名称','类别编号','价格','库存量']list_val=[]r=0#读取“商品名称”列的全部数据,与用户输入的关键词逐一对比for cell_pname in tuple(sheet.columns)[2][1:]:r+=1#符合条件的关键词在于商品名称中if pnm in cell_pname.value:commodity=[cell.value for cell in tuple(sheet.rows)[r]]#填写list_val[],并与list_key[]合并成一个字典记录list_val.append(commodity[0]) #商品号list_val.append(commodity[1]) #商品名称list_val.append(commodity[2]) #类别编号list_val.append(commodity[3]) #价格list_val.append(commodity[4]) #库存#合成为字典dict_com=dict(zip(list_key, list_val))commoditys.append(dict_com)list_val=[]#清除模型里的旧数据self.im.clear()#重新生成表头self.initTableHeader()r=0#遍历商品信息列表,将查询到的记录逐条加载进模型for k, dict_com in enumerate(commoditys):self.im.setItem(r,0,QStandardItem(str(dict_com['商品号'])))self.im.setItem(r,1,QStandardItem(str(dict_com['类别编号'])))self.im.setItem(r,2,QStandardItem(str(dict_com['商品名称'])))self.im.setItem(r,3,QStandardItem(str(dict_com['价格'])))self.im.setItem(r,4,QStandardItem(str(dict_com['库存量'])))r+=1

槽函数绑定信号:

self.pbQue.clicked.connect(self.query)

此时列表信息就会展示出来,如下图:

2.2 图片展示

当我们点击列表商品行的时候,右侧出现图片显示:

此时我们用showImg函数实现:

    def showImg(self):#获取当前行数据row=self.tbvCom.currentIndex().row()index=self.tbvCom.model().index(row,0)pid=self.tbvCom.model().data(index)image=QPixmap(r'image/goods/'+pid+'.jpg')self.lbImg.setPixmap(image)

2.3 选购

选购会思考是否下单过而未结算以及下单过已结算和未下单的情况,分别列出来,做成分支处理。下过单未结算,就是已选购,不需要重复选购,下单过结算了,可以重新下单。未下单的可以直接下单。

    def preShop(self):book=openpyxl.load_workbook(r'data/netshop.xlsx')sheet1=book['订单项表']sheet2=book['订单表']#首先判断该用户在此前有没有选购(尚未结算)过商品#1 找出订单项表中所有状态不为“结算”的记录,将它们对应的订单号放入一个集合r=0set_oid=set()for cell_stat in tuple(sheet1.columns)[3][1:]:r += 1if cell_stat.value != '结算':orderitem=[cell.value for cell in tuple(sheet1.rows)[r]]set_oid.add(orderitem[0])#2 读取订单表的订单号、用户账号列,合成为字典list_oid=[cell.value for cell in tuple(sheet2.columns)[0][1:]]list_uid=[cell.value for cell in tuple(sheet2.columns)[1][1:]]dict_ouid=dict(zip(list_oid,list_uid))#3 用第一步得到的订单号集合到第2步得到的字典中去对比oid =0exist = Falsefor id in enumerate(set_oid):for key_oid, val_uid in dict_ouid.items():if (id[1] == key_oid) and (appvar.getID() ==val_uid):exist=Trueoid=id[1]breakrow =self.tbvCom.currentIndex().row()index=self.tbvCom.model().index(row,0)#若没有比中,说明时初次选购if exist ==False:#读取订单项表的订单号列,生成预备订单号(当前已有订单号最大值+1)list_oid=[cell.value for cell in tuple(sheet1.columns)[0][1:]]if list_oid == []:old=1else:old=max(list_oid)+1pid=eval(self.tbvCom.model().data(index))#写入预备订单项s1r=str(sheet1.max_row+1)sheet1['A'+s1r].alignment=Alignment(horizontal='center')sheet1['B'+s1r].alignment=Alignment(horizontal='center')sheet1['C'+s1r].alignment=Alignment(horizontal='center')sheet1['A' +s1r]=oidsheet1['B'+s1r]=pidsheet1['C'+s1r]=1sheet1['D'+s1r]='选购'#写入预备订单s2r=str(sheet2.max_row +1)sheet2['A'+s2r].alignment=Alignment(horizontal='center')sheet2['A'+s2r]=oidsheet2['B'+s2r]=appvar.getID()#若比中,说明该用户此前已选/订购过商品else:pid=eval(self.tbvCom.model().data(index))#添加此次选购的订单项#确定插入记录的行号s1r=str(sheet1.max_row+1)sheet1['A' + s1r].alignment = Alignment(horizontal='center')sheet1['B' + s1r].alignment = Alignment(horizontal='center')sheet1['C' + s1r].alignment = Alignment(horizontal='center')sheet1['A' + s1r] = oidsheet1['B' + s1r] = pidsheet1['C' + s1r] = 1sheet1['D' + s1r] = '选购'book.save(r'data/netshop.xlsx')book.close()msgbox=QMessageBox.information(self, '提示', '已选购。')print(msgbox)

2.4 打印

点击打印按钮实现打印预览功能,效果如下:

    # 点击打印def printTable(self):#创建打印预览对话框dlg=QPrintPreviewDialog()dlg.paintRequested.connect(self.handlePrint)dlg.exec()# 执行打印函数def handlePrint(self,printer):doc=QTextDocument()cur=QTextCursor(doc)#设定标题文字格式、写标题fmt_textchar=QTextCharFormat()fmt_textchar.setFontFamily('微软雅黑')fmt_textchar.setFontPointSize(10)fmt_textblock=QTextBlockFormat()fmt_textblock.setAlignment(Qt.AlignmentFlag.AlignHCenter)cur.setBlockFormat(fmt_textblock)cur.insertText("商品名称中包含 '"+ self.lePNm.text()+"'", fmt_textchar)#设定表格式fmt_table=QTextTableFormat()fmt_table.setBorder(1)fmt_table.setBorderStyle(QTextTableFormat.BorderStyle.BorderStyle_Solid)fmt_table.setCellSpacing(0)fmt_table.setTopMargin(0)fmt_table.setCellPadding(4)fmt_table.setAlignment(Qt.AlignmentFlag.AlignHCenter)cur.insertTable(self.im.rowCount()+1, self.im.columnCount(),fmt_table)#写表头for i in range(0, self.im.columnCount()):header=self.im.headerData(i, Qt.Orientation.Horizontal)cur.insertText(header)cur.movePosition(QTextCursor.MoveOperation.NextCell)#写表记录for row in range(0,self.im.rowCount()):for col in range(0, self.im.columnCount()):index=self.im.index(row, col)cur.insertText(str(index.data()))cur.movePosition(QTextCursor.MoveOperation.NextCell)doc.print(printer)

3 完整代码

完整代码如下,大家可以参考使用:

UI页面代码:


from PyQt6 import QtCore, QtGui, QtWidgets
from PyQt6.QtWidgets import QMainWindowclass Ui_MainWindow(QMainWindow):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(812, 452)self.centralwidget = QtWidgets.QWidget(parent=MainWindow)self.centralwidget.setObjectName("centralwidget")self.lbTitle = QtWidgets.QLabel(parent=self.centralwidget)self.lbTitle.setGeometry(QtCore.QRect(340, 30, 111, 31))font = QtGui.QFont()font.setPointSize(18)self.lbTitle.setFont(font)self.lbTitle.setLayoutDirection(QtCore.Qt.LayoutDirection.LeftToRight)self.lbTitle.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)self.lbTitle.setObjectName("lbTitle")self.tbvCom = QtWidgets.QTableView(parent=self.centralwidget)self.tbvCom.setGeometry(QtCore.QRect(20, 120, 601, 261))font = QtGui.QFont()font.setPointSize(12)self.tbvCom.setFont(font)self.tbvCom.setSelectionMode(QtWidgets.QAbstractItemView.SelectionMode.SingleSelection)self.tbvCom.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows)self.tbvCom.setObjectName("tbvCom")self.tbvCom.horizontalHeader().setDefaultSectionSize(120)self.tbvCom.horizontalHeader().setMinimumSectionSize(25)self.tbvCom.horizontalHeader().setStretchLastSection(True)self.tbvCom.verticalHeader().setVisible(False)self.lbName = QtWidgets.QLabel(parent=self.centralwidget)self.lbName.setGeometry(QtCore.QRect(20, 90, 71, 16))font = QtGui.QFont()font.setPointSize(12)self.lbName.setFont(font)self.lbName.setObjectName("lbName")self.lePNm = QtWidgets.QLineEdit(parent=self.centralwidget)self.lePNm.setGeometry(QtCore.QRect(100, 90, 121, 21))self.lePNm.setObjectName("lePNm")self.pbQue = QtWidgets.QPushButton(parent=self.centralwidget)self.pbQue.setGeometry(QtCore.QRect(230, 90, 75, 24))font = QtGui.QFont()font.setPointSize(12)self.pbQue.setFont(font)self.pbQue.setObjectName("pbQue")self.lbUsr = QtWidgets.QLabel(parent=self.centralwidget)self.lbUsr.setGeometry(QtCore.QRect(400, 90, 191, 21))font = QtGui.QFont()font.setPointSize(14)self.lbUsr.setFont(font)self.lbUsr.setText("")self.lbUsr.setObjectName("lbUsr")self.lbUserName = QtWidgets.QLabel(parent=self.centralwidget)self.lbUserName.setGeometry(QtCore.QRect(350, 90, 41, 20))font = QtGui.QFont()font.setPointSize(12)self.lbUserName.setFont(font)self.lbUserName.setObjectName("lbUserName")self.pbPrint = QtWidgets.QPushButton(parent=self.centralwidget)self.pbPrint.setGeometry(QtCore.QRect(534, 380, 81, 31))font = QtGui.QFont()font.setPointSize(12)self.pbPrint.setFont(font)self.pbPrint.setObjectName("pbPrint")self.lbPic = QtWidgets.QLabel(parent=self.centralwidget)self.lbPic.setGeometry(QtCore.QRect(690, 120, 54, 16))font = QtGui.QFont()font.setPointSize(12)self.lbPic.setFont(font)self.lbPic.setAlignment(QtCore.Qt.AlignmentFlag.AlignCenter)self.lbPic.setObjectName("lbPic")self.lbImg = QtWidgets.QLabel(parent=self.centralwidget)self.lbImg.setGeometry(QtCore.QRect(653, 160, 141, 131))self.lbImg.setText("")self.lbImg.setScaledContents(True)self.lbImg.setObjectName("lbImg")self.pbPre = QtWidgets.QPushButton(parent=self.centralwidget)self.pbPre.setGeometry(QtCore.QRect(690, 320, 75, 24))font = QtGui.QFont()font.setPointSize(12)self.pbPre.setFont(font)self.pbPre.setObjectName("pbPre")MainWindow.setCentralWidget(self.centralwidget)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "商品选购"))self.lbTitle.setText(_translate("MainWindow", "商品选购"))self.lbName.setText(_translate("MainWindow", "商品名称"))self.pbQue.setText(_translate("MainWindow", "查询"))self.lbUserName.setText(_translate("MainWindow", "用户:"))self.pbPrint.setText(_translate("MainWindow", "打印..."))self.lbPic.setText(_translate("MainWindow", "图片"))self.pbPre.setText(_translate("MainWindow", "选购"))

功能实现逻辑代码:

# -*- coding:utf-8 -*-
"""
------------------------------------------------
File Name: PreShop.py
Description:
Author: lzq
date:2024-08-07 09:10
------------------------------------------------
"""
import sysimport openpyxl as openpyxl
import printer
from PyQt6.QtCore import Qt
from PyQt6.QtGui import QIcon, QPixmap, QStandardItemModel, QStandardItem, QTextDocument, QTextCursor, QTextCharFormat, \QTextBlockFormat, QTextTableFormat
from PyQt6.QtPrintSupport import QPrintPreviewDialog
from PyQt6.QtWidgets import QMessageBox, QApplication
from openpyxl.styles import Alignmentfrom pyqt6Learn.myNetShop import appvar
from pyqt6Learn.myNetShop.ui.PreShop_ui import Ui_MainWindow#存放查询到的商品数据(字典列表)
commoditys=[]
class PreWindow(Ui_MainWindow):def __init__(self):super(PreWindow,self).__init__()self.setupUi(self)self.initUi()def initUi(self):self.setWindowIcon(QIcon('image/netshop.png'))self.setWindowFlag(Qt.WindowType.MSWindowsFixedSizeDialogHint)self.lePNm.returnPressed.connect(self.query)self.pbQue.clicked.connect(self.query)self.tbvCom.clicked.connect(self.showImg)self.pbPrint.clicked.connect(self.printTable)self.pbPre.clicked.connect(self.preShop)#获取当前登录用户账号self.lbUsr.setText(appvar.getID())#生成商品信息表头self.initTableHeader()# 购物车图片self.pbPre.setIcon(QIcon(QPixmap(r'image/cart.png')))def initTableHeader(self):#创建模型self.im=QStandardItemModel()self.im.setHorizontalHeaderItem(0,QStandardItem('商品号'))self.im.setHorizontalHeaderItem(1,QStandardItem('商品名称'))self.im.setHorizontalHeaderItem(2,QStandardItem('类别'))self.im.setHorizontalHeaderItem(3,QStandardItem('价格'))self.im.setHorizontalHeaderItem(4,QStandardItem('库存量'))self.tbvCom.setModel(self.im)#设置表格各列的宽度self.tbvCom.setColumnWidth(0,70)self.tbvCom.setColumnWidth(1,300)self.tbvCom.setColumnWidth(2,60)self.tbvCom.setColumnWidth(3,70)self.tbvCom.setColumnWidth(4,40)def query(self):global commodityspnm=self.lePNm.text()book=openpyxl.load_workbook(r'data/netshop.xlsx')sheet=book['商品表']commoditys=[]list_key=['商品号','商品名称','类别编号','价格','库存量']list_val=[]r=0#读取“商品名称”列的全部数据,与用户输入的关键词逐一对比for cell_pname in tuple(sheet.columns)[2][1:]:r+=1#符合条件的关键词在于商品名称中if pnm in cell_pname.value:commodity=[cell.value for cell in tuple(sheet.rows)[r]]#填写list_val[],并与list_key[]合并成一个字典记录list_val.append(commodity[0]) #商品号list_val.append(commodity[1]) #商品名称list_val.append(commodity[2]) #类别编号list_val.append(commodity[3]) #价格list_val.append(commodity[4]) #库存#合成为字典dict_com=dict(zip(list_key, list_val))commoditys.append(dict_com)list_val=[]#清除模型里的旧数据self.im.clear()#重新生成表头self.initTableHeader()r=0#遍历商品信息列表,将查询到的记录逐条加载进模型for k, dict_com in enumerate(commoditys):self.im.setItem(r,0,QStandardItem(str(dict_com['商品号'])))self.im.setItem(r,1,QStandardItem(str(dict_com['类别编号'])))self.im.setItem(r,2,QStandardItem(str(dict_com['商品名称'])))self.im.setItem(r,3,QStandardItem(str(dict_com['价格'])))self.im.setItem(r,4,QStandardItem(str(dict_com['库存量'])))r+=1def showImg(self):print("展示图片")row=self.tbvCom.currentIndex().row()index=self.tbvCom.model().index(row,0)pid=self.tbvCom.model().data(index)image=QPixmap(r'image/goods/'+pid+'.jpg')self.lbImg.setPixmap(image)def printTable(self):#创建打印预览对话框dlg=QPrintPreviewDialog()dlg.paintRequested.connect(self.handlePrint)dlg.exec()def handlePrint(self,printer):doc=QTextDocument()cur=QTextCursor(doc)#设定标题文字格式、写标题fmt_textchar=QTextCharFormat()fmt_textchar.setFontFamily('微软雅黑')fmt_textchar.setFontPointSize(10)fmt_textblock=QTextBlockFormat()fmt_textblock.setAlignment(Qt.AlignmentFlag.AlignHCenter)cur.setBlockFormat(fmt_textblock)cur.insertText("商品名称中包含 '"+ self.lePNm.text()+"'", fmt_textchar)#设定表格式fmt_table=QTextTableFormat()fmt_table.setBorder(1)fmt_table.setBorderStyle(QTextTableFormat.BorderStyle.BorderStyle_Solid)fmt_table.setCellSpacing(0)fmt_table.setTopMargin(0)fmt_table.setCellPadding(4)fmt_table.setAlignment(Qt.AlignmentFlag.AlignHCenter)cur.insertTable(self.im.rowCount()+1, self.im.columnCount(),fmt_table)#写表头for i in range(0, self.im.columnCount()):header=self.im.headerData(i, Qt.Orientation.Horizontal)cur.insertText(header)cur.movePosition(QTextCursor.MoveOperation.NextCell)#写表记录for row in range(0,self.im.rowCount()):for col in range(0, self.im.columnCount()):index=self.im.index(row, col)cur.insertText(str(index.data()))cur.movePosition(QTextCursor.MoveOperation.NextCell)doc.print(printer)#选购功能函数def preShop(self):book=openpyxl.load_workbook(r'data/netshop.xlsx')sheet1=book['订单项表']sheet2=book['订单表']#首先判断该用户在此前有没有选购(尚未结算)过商品#1 找出订单项表中所有状态不为“结算”的记录,将它们对应的订单号放入一个集合r=0set_oid=set()for cell_stat in tuple(sheet1.columns)[3][1:]:r += 1if cell_stat.value != '结算':orderitem=[cell.value for cell in tuple(sheet1.rows)[r]]set_oid.add(orderitem[0])#2 读取订单表的订单号、用户账号列,合成为字典list_oid=[cell.value for cell in tuple(sheet2.columns)[0][1:]]list_uid=[cell.value for cell in tuple(sheet2.columns)[1][1:]]dict_ouid=dict(zip(list_oid,list_uid))#3 用第一步得到的订单号集合到第2步得到的字典中去对比oid =0exist = Falsefor id in enumerate(set_oid):for key_oid, val_uid in dict_ouid.items():if (id[1] == key_oid) and (appvar.getID() ==val_uid):exist=Trueoid=id[1]breakrow =self.tbvCom.currentIndex().row()index=self.tbvCom.model().index(row,0)#若没有比中,说明时初次选购if exist ==False:#读取订单项表的订单号列,生成预备订单号(当前已有订单号最大值+1)list_oid=[cell.value for cell in tuple(sheet1.columns)[0][1:]]if list_oid == []:old=1else:old=max(list_oid)+1pid=eval(self.tbvCom.model().data(index))#写入预备订单项s1r=str(sheet1.max_row+1)sheet1['A'+s1r].alignment=Alignment(horizontal='center')sheet1['B'+s1r].alignment=Alignment(horizontal='center')sheet1['C'+s1r].alignment=Alignment(horizontal='center')sheet1['A' +s1r]=oidsheet1['B'+s1r]=pidsheet1['C'+s1r]=1sheet1['D'+s1r]='选购'#写入预备订单s2r=str(sheet2.max_row +1)sheet2['A'+s2r].alignment=Alignment(horizontal='center')sheet2['A'+s2r]=oidsheet2['B'+s2r]=appvar.getID()#若比中,说明该用户此前已选/订购过商品else:pid=eval(self.tbvCom.model().data(index))#添加此次选购的订单项#确定插入记录的行号s1r=str(sheet1.max_row+1)sheet1['A' + s1r].alignment = Alignment(horizontal='center')sheet1['B' + s1r].alignment = Alignment(horizontal='center')sheet1['C' + s1r].alignment = Alignment(horizontal='center')sheet1['A' + s1r] = oidsheet1['B' + s1r] = pidsheet1['C' + s1r] = 1sheet1['D' + s1r] = '选购'book.save(r'data/netshop.xlsx')book.close()msgbox=QMessageBox.information(self, '提示', '已选购。')print(msgbox)

本文至此结束,喜欢点赞关注,您的关注和点赞是路卿进步的动力哦!老Baby们!!!

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 深入理解 Go 语言并发 map 安全使用
  • 【SpringBoot3】双向实时通讯 websocket
  • 第二章 方法与方法重载
  • 在HFSS中对曲线等结构进行分割(Split)
  • ubuntu 安装两个nginx实例时的坑,非默认nginx实例配置修改总也不生效的问题
  • HTML及CSS面试题4
  • 66_1JSON【浏览器中处理JSON、Java中处理JSON(FastJSON、Jackson)】、Java中的bean
  • XML外部实体注入
  • 使用docxtemplater-image-module-free时支持动态获取图片大小
  • SpringBoot:将单体项目拆分成微服务项目
  • 【PGCCC】pg_bestmatch.rs:使用 BM25 提升您的 PostgreSQL 文本查询#PCA
  • Windows下添加开机启动项
  • Vue.js 中的指令(Vue自定义指令)
  • 在小程序添加公司官网访问
  • 使用 Vue 2 搭建后台管理系统
  • angular2开源库收集
  • Apache Spark Streaming 使用实例
  • java架构面试锦集:开源框架+并发+数据结构+大企必备面试题
  • js
  • react 代码优化(一) ——事件处理
  • Redis在Web项目中的应用与实践
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • Solarized Scheme
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 观察者模式实现非直接耦合
  • 近期前端发展计划
  • 快速体验 Sentinel 集群限流功能,只需简单几步
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 如何进阶一名有竞争力的程序员?
  • 突破自己的技术思维
  • 不要一棍子打翻所有黑盒模型,其实可以让它们发挥作用 ...
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • #git 撤消对文件的更改
  • (el-Transfer)操作(不使用 ts):Element-plus 中 Select 组件动态设置 options 值需求的解决过程
  • (十)T检验-第一部分
  • (转)重识new
  • *** 2003
  • .NET CF命令行调试器MDbg入门(一)
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .Net的C#语言取月份数值对应的MonthName值
  • .net企业级架构实战之7——Spring.net整合Asp.net mvc
  • .net通用权限框架B/S (三)--MODEL层(2)
  • 。。。。。
  • /etc/sudoer文件配置简析
  • @Value读取properties中文乱码解决方案
  • []AT 指令 收发短信和GPRS上网 SIM508/548
  • [20180312]进程管理其中的SQL Server进程占用内存远远大于SQL server内部统计出来的内存...
  • [22]. 括号生成
  • [Angular] 笔记 8:list/detail 页面以及@Input
  • [BZOJ 4129]Haruna’s Breakfast(树上带修改莫队)
  • [C++]priority_queue的介绍及模拟实现
  • [C++]类和对象(中)
  • [Cloud Networking] Layer 2