PyQt5入门(十二)复杂控件 视图 & MVC设计模式 & 表格(上)

目录

一.显示二维表数据

二.显示列数据

三.扩展的列表控件

四.扩展的表格控件

五.在单元格中放置控件

六.在表格中搜索Cell和行定位

七.设置单元格字体和颜色

八.按表格的某一列排序


从本讲开始学习复杂控件。加油!

一.显示二维表数据

显示二维表数据(QTableVi ew控件)

数据源 Model

需要创建QTableView实例和一个数据源(Model) ,然后将两者关联,这个体系类似于MVC模式。

一个QTableView实例可以存放不同的数据源,一个数据源也可以对应不同的QTableView实例。

MVC: Model  Viewer  Controller 即将数据Model和前端视图Viewer分离,通过控制器Controller 来控制。

MVC的目的是将后端的数据和前端页面的耦合度降低。

代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *


class TableView(QWidget):
    def __init__(self):
        super(TableView, self).__init__()
        self.setWindowTitle('QTableView表格视图控件演示')
        self.resize(500,300)

        self.model=QStandardItemModel(4,3)#二维表4行3列
        #数据表的字段
        self.model.setHorizontalHeaderLabels(['id','name','age'])

        self.tableView=QTableView()
        #关联QTableView控件和Model
        self.tableView.setModel(self.model)

        #添加数据
        item11=QStandardItem('1') #一个QStandardItem就是一个单元格
        item12 = QStandardItem('Kobe')
        item13 = QStandardItem('24')
        self.model.setItem(0,0,item11)
        self.model.setItem(0, 1, item12)
        self.model.setItem(0, 2, item13)
        #可跳行添加数据
        item31 = QStandardItem('7')
        item32 = QStandardItem('Durant')
        item33 = QStandardItem('35')
        self.model.setItem(2, 0, item31)
        self.model.setItem(2, 1, item32)
        self.model.setItem(2, 2, item33)

        #垂直布局
        layout=QVBoxLayout()
        layout.addWidget(self.tableView)
        self.setLayout(layout)


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=TableView()
    main.show()
    sys.exit(app.exec_())

运行结果:

二.显示列数据

代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QStringListModel


class ListView(QWidget):
    def __init__(self):
        super(ListView, self).__init__()
        self.setWindowTitle('ListView例子')
        self.resize(300,270)
        layout=QVBoxLayout()

        listView=QListView()
        #数据源
        listModel=QStringListModel()
        self.list=['列表项1','列表项2','列表项3']
        listModel.setStringList(self.list)
        
        #关联视图与数据源
        listView.setModel(listModel)
        
        listView.clicked.connect(self.clicked)
        layout.addWidget(listView)

        self.setLayout(layout)

    def clicked(self,item):
        QMessageBox.information(self,'QListView','您选择了:'+self.list[item.row()])


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=ListView()
    main.show()
    sys.exit(app.exec_())

运行结果:

三.扩展的列表控件

代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import QStringListModel

'''
QListWidget是QListView的子类
添加了很多API,支持MVC模式,也支持非MVC模式,即数据直接添加到控件上
'''


class ListWidget(QMainWindow):
    def __init__(self):
        super(ListWidget, self).__init__()
        self.setWindowTitle('ListWidget例子')
        self.resize(300,270)

        #直接添加的方式适合少量的数据的时候
        self.listWidget=QListWidget()
        #self.listWidget.resize(300,120)
        self.listWidget.addItem('item1')
        self.listWidget.addItem('item2')
        self.listWidget.addItem('item3')
        self.listWidget.addItem('item4')
        self.listWidget.addItem('item5')

        self.listWidget.itemClicked.connect(self.clicked)
        #设置中心控件之后,会铺满整个屏幕,无需再单独设置listWidget尺寸
        self.setCentralWidget(self.listWidget)

    def clicked(self,index):
        QMessageBox.information(self,'ListWidget','您选择了:'+self.listWidget.item(self.listWidget.row(index)).text())


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=ListWidget()
    main.show()
    sys.exit(app.exec_())

运行结果:

四.扩展的表格控件

每一个Cell (单元格) 是一个QTableWidgetItem

代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

'''
QTableWidget是QTableView的子类
添加了很多API,支持MVC模式,也支持非MVC模式,即数据直接添加到控件上
'''
class TableWidget(QWidget):
    def __init__(self):
        super(TableWidget, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('QTableWidget演示')
        self.resize(430, 230)

        layout = QHBoxLayout()
        tablewidget = QTableWidget()
        # 4行3列
        tablewidget.setRowCount(4)
        tablewidget.setColumnCount(3)

        tablewidget.setHorizontalHeaderLabels(['name','age','address'])

        nameItem=QTableWidgetItem('小明')
        tablewidget.setItem(0,0,nameItem)
        ageItem = QTableWidgetItem('24')
        tablewidget.setItem(0, 1, ageItem)
        addressItem = QTableWidgetItem('北京')
        tablewidget.setItem(0, 2, addressItem)
        #禁止编辑
        tablewidget.setEditTriggers(QAbstractItemView.NoEditTriggers)
        #整行选择
        tablewidget.setSelectionBehavior(QAbstractItemView.SelectRows)
        #调整列和行
        tablewidget.resizeColumnsToContents()
        tablewidget.resizeRowsToContents()
        #隐藏表格头
        tablewidget.horizontalHeader().setVisible(False) #隐藏水平方向的表格头
        #tablewidget.verticalHeader().setVisible(False) #隐藏垂直方向的表格头
        #设置表格头内容
        tablewidget.setVerticalHeaderLabels(['a','b']) #垂直方向表格头前两个设为a,b
        #隐藏表格线
        tablewidget.setShowGrid(False)

        layout.addWidget(tablewidget)
        self.setLayout(layout)


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=TableWidget()
    main.show()
    sys.exit(app.exec_())

运行结果:

五.在单元格中放置控件

在单元格中放置控件
setItem:将文本放到单元格中
setCellWidget:将控件放到单元格中
setStyleSheet设置控件的样式(QSS)

代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *

'''
QTableWidget是QTableView的子类
添加了很多API,支持MVC模式,也支持非MVC模式,即数据直接添加到控件上
'''
class TableWidget(QWidget):
    def __init__(self):
        super(TableWidget, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('在单元格中放置控件')
        self.resize(430, 300)

        layout = QHBoxLayout()
        tableWidget = QTableWidget()
        # 4行3列
        tableWidget.setRowCount(4)
        tableWidget.setColumnCount(3)

        tableWidget.setHorizontalHeaderLabels(['name','age','weigh(kg)'])

        textItem=QTableWidgetItem('小明')
        #setItem:将文本放到单元格中
        tableWidget.setItem(0,0,textItem)

        #下拉框
        combox=QComboBox()
        combox.addItem('男')
        combox.addItem('女')
        #setStyleSheet设置控件的样式(QSS)(类似于web中的CSS),即Qt StyleSheet(n.样式表)
        combox.setStyleSheet('QComboBox{margin:3px};')#设置控键距离上下左右的单元格的距离(距离)
        #setCellWidget:将控件放到单元格中
        tableWidget.setCellWidget(0,1,combox)

        modifyButton=QPushButton('修改')
        #默认是按下的状态
        modifyButton.setDown(True)
        modifyButton.setStyleSheet('QPushButton{margin:3px};')
        tableWidget.setCellWidget(0,2,modifyButton)

        layout.addWidget(tableWidget)
        self.setLayout(layout)


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=TableWidget()
    main.show()
    sys.exit(app.exec_())

运行结果:

六.在表格中搜索Cell和行定位

在表格中快速定位到特定的行
1.数据的定位: findItems ,返回一个列表
2.如果找到了满足条件的单元格,会定位到单元格所在的行: setSliderPosition(row)

代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class DataLocation(QWidget):
    def __init__(self):
        super(DataLocation, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('在表格中搜索Cell和行定位')
        self.resize(600, 800)

        layout = QHBoxLayout()
        tableWidget=QTableWidget()
        tableWidget.setRowCount(40)
        tableWidget.setColumnCount(4)

        for i in range(40):
            for j in range(4):
                itemContent='(%d,%d)'%(i,j)
                tableWidget.setItem(i,j,QTableWidgetItem(itemContent))
        self.setLayout(layout)
        #搜索满足条件的Cell
        text='(13,1)'
        text1='(1,'
        #参数一:要匹配的文本 ; 参数二:搜索模式,返回一个列表
        #items=tableWidget.findItems(text,Qt.MatchExactly)#搜索模式设为精确匹配,必须一模一样才行
        items = tableWidget.findItems(text1, Qt.MatchStartsWith)#搜索模式为匹配以...为开头的字符串,这里看text1,即以(1,开头的的字符串
        length=len(items)
        if length>0:
            print('匹配项个数:',len(items))
            for i in range(length):
                item = items[i]
                # 背景色
                item.setBackground(QBrush(QColor(0, 255, 0)))  # rgb
                # 前景色,即文字的颜色
                item.setForeground(QBrush(QColor(255, 0, 0)))
                # 当前项所在的行
                row = item.row()
                # 定位到指定的行
                tableWidget.verticalScrollBar().setSliderPosition(row)


        layout.addWidget(tableWidget)
        self.setLayout(layout)


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=DataLocation()
    main.show()
    sys.exit(app.exec_())

运行结果:

 

七.设置单元格字体和颜色

代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class CellFontAndColor(QWidget):
    def __init__(self):
        super(CellFontAndColor, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('设置单元格字体和颜色')
        self.resize(430, 230)

        layout = QHBoxLayout()
        tableWidget=QTableWidget()
        tableWidget.setRowCount(4)
        tableWidget.setColumnCount(3)

        tableWidget.setHorizontalHeaderLabels(['name','sex','weigh(kg)'])

        newItem=QTableWidgetItem('小明')#单元格的数据项
        newItem.setFont(QFont('Times',14,QFont.Black))#字体,字号,颜色
        newItem.setForeground(QBrush(QColor(255,0,0)))
        tableWidget.setItem(0,0,newItem)

        newItem = QTableWidgetItem('女')
        newItem.setForeground(QBrush(QColor(255, 255, 0)))
        newItem.setBackground(QBrush(QColor(0,0,255)))#rgb
        tableWidget.setItem(0, 1, newItem)

        newItem = QTableWidgetItem('100')
        newItem.setFont(QFont('Times', 20, QFont.Black))
        newItem.setForeground(QBrush(QColor(0, 0, 255)))
        tableWidget.setItem(0, 2, newItem)

        layout.addWidget(tableWidget)
        self.setLayout(layout)


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=CellFontAndColor()
    main.show()
    sys.exit(app.exec_())

运行结果:

八.按表格的某一列排序

按列排序
1.按哪一列排序
2.排序类型:升序或降序
sortItems( columnIndex,orderType)

代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *


class CellFontAndColor(QWidget):
    def __init__(self):
        super(CellFontAndColor, self).__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('设置单元格字体和颜色')
        self.resize(540, 230)

        layout = QHBoxLayout()
        self.tableWidget=QTableWidget()#表格对象
        self.tableWidget.setRowCount(4)
        self.tableWidget.setColumnCount(3)

        self.tableWidget.setHorizontalHeaderLabels(['name','sex','weigh(kg)'])

        #添加数据
        newItem=QTableWidgetItem('张三')
        self.tableWidget.setItem(0,0,newItem)
        newItem = QTableWidgetItem('男')
        self.tableWidget.setItem(0, 1, newItem)
        newItem = QTableWidgetItem('165')
        self.tableWidget.setItem(0, 2, newItem)

        newItem = QTableWidgetItem('李四')
        self.tableWidget.setItem(1, 0, newItem)
        newItem = QTableWidgetItem('女')
        self.tableWidget.setItem(1, 1, newItem)
        newItem = QTableWidgetItem('120')
        self.tableWidget.setItem(1, 2, newItem)

        newItem = QTableWidgetItem('王五')
        self.tableWidget.setItem(2, 0, newItem)
        newItem = QTableWidgetItem('男')
        self.tableWidget.setItem(2, 1, newItem)
        newItem = QTableWidgetItem('130')
        self.tableWidget.setItem(2, 2, newItem)

        #点击按钮排序
        self.btn=QPushButton('升序')
        self.btn.clicked.connect(self.order)
        #常量
        self.orderType=Qt.DescendingOrder

        layout.addWidget(self.tableWidget)
        layout.addWidget(self.btn)
        self.setLayout(layout)

    #升降序来回切换
    def order(self):
        if self.orderType == Qt.DescendingOrder:
            self.orderType=Qt.AscendingOrder
            self.btn.setText('降序')#重命名按钮名,setText设置按钮显示文本
        else:
            self.orderType = Qt.DescendingOrder
            self.btn.setText('升序')
        #print(Qt.DescendingOrder)
        #print(self.orderType)
        self.tableWidget.sortItems(2,self.orderType)#按照第三列的数据项排序
        #self.tableWidget.sortItems(2, Qt.DescendingOrder)


if __name__=='__main__':
    app=QApplication(sys.argv)
    main=CellFontAndColor()
    main.show()
    sys.exit(app.exec_())

运行结果:

点击排序每次是升序和降序依次切换。

(初始状态)  (升序后) (降序后)

猜你喜欢

转载自blog.csdn.net/weixin_44593822/article/details/113507483
今日推荐