清风徐来
Michael's Blog
PyQt5表格应用的详细Demo

PyQt5实现的一个表格应用的 demo。涉及的知识点:tableWidget 的基本使用,cell 内放置 widget,设置 cell 模式,分页,获取选中项目。 PyQt5TableWidgetDemo.PNG

首先是 QtDesigner 设计, 一个 tablewidget,4个 pushbuttno:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QTableWidget" name="tableWidget">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>0</y>
      <width>801</width>
      <height>541</height>
     </rect>
    </property>
    <property name="rowCount">
     <number>5</number>
    </property>
    <property name="columnCount">
     <number>11</number>
    </property>
    <row/>
    <row/>
    <row/>
    <row/>
    <row/>
    <column/>
    <column/>
    <column/>
    <column/>
    <column/>
    <column/>
    <column/>
   </widget>
   <widget class="QWidget" name="horizontalLayoutWidget">
    <property name="geometry">
     <rect>
      <x>0</x>
      <y>540</y>
      <width>801</width>
      <height>31</height>
     </rect>
    </property>
    <layout class="QHBoxLayout" name="horizontalLayout">
     <item>
      <widget class="QPushButton" name="btnLoad">
       <property name="text">
        <string>Load</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="btnPre">
       <property name="text">
        <string>《Pre</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="btnNext">
       <property name="text">
        <string>Next》</string>
       </property>
      </widget>
     </item>
     <item>
      <widget class="QPushButton" name="btnDetail">
       <property name="text">
        <string>Detail</string>
       </property>
      </widget>
     </item>
    </layout>
   </widget>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

生成的 ui 代码 tableWidgetDemo.py:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'tableWidgetDemo.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(0, 0, 801, 541))
        self.tableWidget.setRowCount(5)
        self.tableWidget.setColumnCount(11)
        self.tableWidget.setObjectName("tableWidget")
        self.horizontalLayoutWidget = QtWidgets.QWidget(self.centralwidget)
        self.horizontalLayoutWidget.setGeometry(QtCore.QRect(0, 540, 801, 31))
        self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
        self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
        self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.btnLoad = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.btnLoad.setObjectName("btnLoad")
        self.horizontalLayout.addWidget(self.btnLoad)
        self.btnPre = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.btnPre.setObjectName("btnPre")
        self.horizontalLayout.addWidget(self.btnPre)
        self.btnNext = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.btnNext.setObjectName("btnNext")
        self.horizontalLayout.addWidget(self.btnNext)
        self.btnDetail = QtWidgets.QPushButton(self.horizontalLayoutWidget)
        self.btnDetail.setObjectName("btnDetail")
        self.horizontalLayout.addWidget(self.btnDetail)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.btnLoad.setText(_translate("MainWindow", "Load"))
        self.btnPre.setText(_translate("MainWindow", "《Pre"))
        self.btnNext.setText(_translate("MainWindow", "Next》"))
        self.btnDetail.setText(_translate("MainWindow", "Detail"))

最后上实现代码:

from PyQt5 import QtWidgets, QtCore
import sqlite3

from tableWidgetDemo import Ui_MainWindow

class Window(QtWidgets.QMainWindow):
    def  __init__(self, parent=None):
        super(Window, self).__init__(parent=parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.initStyle()
        self.initConn()

        self.currentPage = 1

        self.ui.btnLoad.clicked.connect(lambda :self.loadData(1))
        self.ui.btnDetail.clicked.connect(self.showDetail)
        self.ui.btnPre.clicked.connect(lambda : self.loadData(self.currentPage - 1))
        self.ui.btnNext.clicked.connect(lambda : self.loadData(self.currentPage + 1))

    def closeEvent(self, event):
        self.connection.close()
        event.accept()

    def initStyle(self):
        horizontalHeader = ['CustomerID','FirstName','LastName','Company','Address','City','State','国籍','邮编','电话',"Action"]
        self.ui.tableWidget.setHorizontalHeaderLabels(horizontalHeader)

    def initConn(self):
        self.connection = sqlite3.connect("mydb.db")
        self.cur = self.connection.cursor()

    def saveLine(self,id):
        print("saveLine id %d" % id)

    def delLine(self,id):
        print("delLine id %d" % id)

    def createInnerButton(self,id):
        widget = QtWidgets.QWidget()
        saveBtn = QtWidgets.QPushButton("Save")
        saveBtn.setStyleSheet("background-color:DarkSeaGreen;border-style:outset;border-radius:3px")
        saveBtn.setFixedSize(40,14)
        saveBtn.clicked.connect(lambda: self.saveLine(id))

        delBtn = QtWidgets.QPushButton("Del")
        delBtn.setStyleSheet("background-color:LightCoral;border-style:outset;border-radius:3px")
        delBtn.setFixedSize(40,14)
        delBtn.clicked.connect(lambda: self.delLine(id))

        layout = QtWidgets.QHBoxLayout()
        layout.addWidget(saveBtn)
        layout.addWidget(delBtn)
        widget.setLayout(layout)
        return widget

    def showDetail(self):
        select = self.ui.tableWidget.selectedItems()
        if select:
            print(select)
            try:
                print(select[0].text())
                rs = ",".join([i.text() for i in select])
                QtWidgets.QMessageBox.about(self, '你选择的项目', rs)
            except Exception as e:
                print(e)
        else:
            print("Nothing.")


    def loadData(self, page = 1):

        if page < 1:
            QtWidgets.QMessageBox.about(self, '提示', "提示:已经到第一页了\t")
            return

        pageSize = 16
        offset = (page - 1) * pageSize
        query = "SELECT CustomerID,FirstName,LastName,Company,Address,City,State,Country,PostalCode,Phone FROM customers"
        query += " limit %d offset %d" % (pageSize, offset)
        self.cur.execute(query)

        result = self.cur.fetchall()

        if len(result) == 0:
            QtWidgets.QMessageBox.about(self, '提示', "提示:没有下一页了\t")
            return

        self.currentPage = page

        self.ui.tableWidget.setRowCount(0)
        for row_number, row_data in enumerate(result):
            self.ui.tableWidget.insertRow(row_number)
            for colum_number, data in enumerate(row_data):
                self.ui.tableWidget.setItem(row_number, colum_number, QtWidgets.QTableWidgetItem(str(data)))

            temp = QtWidgets.QTableWidgetItem()
            temp.setFlags(QtCore.Qt.ItemIsEnabled)
            self.ui.tableWidget.setItem(row_number,10,temp)

            actionItem = self.createInnerButton(row_data[0])
            self.ui.tableWidget.setCellWidget(row_number,10,actionItem)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Window()
    w.show()
    sys.exit(app.exec_())

最后,给出源码: PyQt5TableWidgetDemo.zip


最后修改于 2017-09-13