Introduction to PyQt5 (12) Complex control view & MVC design pattern & form (on)

table of Contents

1. Display two-dimensional table data

2. Display column data

Three. Extended list control

4. Extended table controls

Five. Place the control in the cell

6. Search Cell and row positioning in the table

7. Set the cell font and color

8. Sort by a column of the table


Start learning complex controls from this lecture. Come on!

1. Display two-dimensional table data

Display two-dimensional table data (QTableVi ew control)

Data source Model

Need to create a QTableView instance and a data source (Model), and then associate the two, this system is similar to the MVC pattern.

A QTableView instance can store different data sources, and a data source can also correspond to different QTableView instances.

MVC: Model Viewer Controller separates the data Model from the front-end view Viewer, and controls it through the Controller.

The purpose of MVC is to reduce the coupling between the back-end data and the front-end page.

 

Code:

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_())

operation result:

 

2. Display column data

Code:

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_())

operation result:

 

Three. Extended list control

Code:

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_())

operation result:

 

4. Extended table controls

Each Cell (cell) is a QTableWidgetItem

Code:

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_())

operation result:

 

Five. Place the control in the cell

Place the control in the cell
setItem: place the text in the cell
setCellWidget: place the control in the cell
setStyleSheet set the style of the control (QSS)

 

Code:

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_())

operation result:

 

6. Search Cell and row positioning in the table

Quickly locate a specific row in the table
1. Data positioning: findItems, return a list
2. If a cell that meets the conditions is found, it will locate the row of the cell: setSliderPosition(row)

 

Code:

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_())

operation result:

 

 

7. Set the cell font and color

Code:

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_())

operation result:

 

8. Sort by a column of the table

Sort by column
1. Sort by which column
2. Sort type: ascending or descending
sortItems( columnIndex, orderType)

 

Code:

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_())

operation result:

Click to sort each time to switch between ascending order and descending order.

(Initial state)  (after ascending order) (after descending order)

 

 

 

 

 

Guess you like

Origin blog.csdn.net/weixin_44593822/article/details/113507483