PyQT5 QTableView的简单应用
此文章是笔者在使用pyqt5编写GUI程序碰到问题时候的随笔,方便自己回头复习。欢迎大家留言指正,共同讨论学习。
一.PyQT5简介
PyQt5是基于Digia公司强大的图形程式框架 Qt5 的python接口,由一组python模块构成,同时支持python2和python3, 笔者使用的是python3 版本。PyQt5本身拥有超过620个类和6000函数及方法。在可以运行于多个平台,包括:Unix, Windows, and Mac OS。
二.QTableView介绍
QTableView类用于以表格形式输出信息,可通过自定义的数据模型来显示数据,通过setModel来绑定数据源。
创建一个表格视图
self.table_view = QTableView()
1.表格标题栏(表头)的操作
设置表格标题栏的字体
font = self.table_view.horizontalHeader().font() # 获取当前表格标题栏的字体
font.setFamily("微软雅黑") # 修改字体样式
self.table_view.horizontalHeader().setFont(font) # 重新设置新的字体
设置表格标题是否可见(True: 可见,False:不可见)
self.table_view.verticalHeader().setVisible(False) # 垂直标题栏不可见
self.table_view.horizontalHeader().setVisible(False) # 水平标题栏不可见
设置表格标题栏是否可被点击
self.table_view.verticalHeader().setSectionsClickable(False) # 垂直标题栏不可被点击
self.table_view.horizontalHeader().setSectionsClickable(False) # 水平标题栏不可被点击
设置表格标题栏的背景色
self.table_view.horizontalHeader().setStyleSheet("QHeaderView::section{background:red;}") # 垂直标题栏背景色为红色
设置表格标题栏的高度
self.table_view.horizontalHeader().setFixedHeight(40)
拖动表格标题栏移动行列
self.table_view.horizontalHeader().setSectionsMovable(True); # 设置可拖动
self.table_view.horizontalHeader().setDragEnabled(True); # 启动拖动
self.table_view.horizontalHeader().setDragDropMode(QAbstractItemView.InternalMove) # 设置拖动模式
2.表格的操作
设置行列填满窗口
self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch) # 使表宽度自适应
self.table_view.verticalHeader().setSectionResizeMode(QHeaderView.Stretch) # 使表高度自适应
设置内容与表格相匹配(当设置填满窗口时 就不可以拉伸表头)
self.table_view.resizeColumnsToContents()
self.table_view.resizeRowsToContents()
当一个单元格的内容很长时 通过设置表头来显示完整的单元格内容
self.table_view.horizontalHeader().setSectionResizeMode(QHeaderView.ResizeToContents)
设置单元格的选中模式(QAbstractItemView共有五种选中模式)
self.table_view.setSelectionMode(QAbstractItemView.SingleSelection) # 选中一个单元格
五种选中模式如下:
模式 | 说明 |
---|---|
QAbstractItemView.NoSelection | 禁止选择 |
QAbstractItemView.SingleSelection | 选中单个目标 |
QAbstractItemView.MultiSelection | 选中多个目标 |
QAbstractItemView.ExtendedSelection | shift键的连续选择 |
QAbstractItemView.ContiguousSelection | ctrl键的不连续的多个选择 |
禁止编辑(QAbstractItemView有七种编辑模式)
self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
七种编辑模式如下:
模式 | 值 | 说明 |
---|---|---|
QAbstractItemView.NoEditTriggers | 0 | 禁止编辑 |
QAbstractItemView.CurrentChanged | 1 | 选择视图中新的数据时触发编辑 |
QAbstractItemView.DoubleClicked | 2 | 鼠标双击时触发编辑 |
QAbstractItemView.SelectedClicked | 4 | 在一个已经选中的行中单击鼠标时触发编辑 |
QAbstractItemView.EditKeyPressed | 8 | 在一个视图选中行中点击鼠标时触发编辑 |
QAbstractItemView.AnyKeyPressed | 16 | 在当前选中的数据(单元格)按下任意键触发当前数据项进入编辑状态 |
QAbstractItemView.AllEditTriggers | 31 | 以上所有操作行为都触发当前数据项进入编辑状态 |
设置选中背景色
self.table_view.setStyleSheet("selection-background-color:lightblue;")
设置是否启用滚动条
self.table_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn) # 启用水平滚动条
self.table_view.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # 禁用水平滚动条
设置单元格的尺寸
self.table_view.setColumnWidth(0, 100) # (固定值0,宽度)
3.获取表格数据
self.table_view.currentIndex().row() # 获取所在行数
self.table_view.currentIndex().column() # 获取所在列数
获得单元格的内容
self.table_view.currentIndex().data()
三. 代码示例
table_view.py
#!/usr/bin/python3
# -*- coding:utf-8 -*-
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QStandardItemModel, QStandardItem, QCursor, QFont
from PyQt5.QtWidgets import (QWidget, QTableView, QAbstractItemView, QToolTip, qApp, QPushButton,
QLabel, QVBoxLayout, QHBoxLayout, QApplication)
class QTableViewPanel(QWidget):
def __init__(self, users_data):
super().__init__()
self.users_data = users_data
self.users_num = len(users_data)
self.user_info_num = len(self.users_data[0])
self.init_ui()
self.main()
def init_ui(self):
""" 界面初始化 """
self.resize(930, 263) # 设置窗口 宽 高
self.setWindowTitle("QTableView界面") # 设置窗口标题
self.setFixedSize(self.width(), self.height())
def set_table_attribute(self):
""" 设置窗口的一些属性 """
self.set_table_column_row()
self.set_table_header()
self.set_table_init_data()
self.set_table_v()
self.set_table_size()
self.set_table_select()
self.set_table_select_mode()
self.set_table_header_visible()
self.set_table_edit_trigger()
self.show_table_grid()
self.set_table_header_font_color()
def set_table_column_row(self):
""" 设置表格 行与列"""
self.model = QStandardItemModel(5, 6)
def set_table_v(self):
""" 设置窗口使用的表格视图 """
self.table_view = QTableView()
self.table_view.setModel(self.model)
def set_table_header(self):
""" 设置表格的表头名称 """
self.column_name = ['user_id', 'user_name', 'company_address', 'telephone', 'email_address', 'remark']
self.model.setHorizontalHeaderLabels(self.column_name)
def set_table_init_data(self):
""" 给表格输入初始化数据 """
for i in range(self.users_num):
for j in range(self.user_info_num):
user_info = QStandardItem(self.users_data[i][j])
self.model.setItem(i, j, user_info)
user_info.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
def set_table_size(self):
""" 设置表格单元格尺寸 """
self.table_view.setColumnWidth(0, 100)
self.table_view.setColumnWidth(1, 130)
self.table_view.setColumnWidth(2, 150)
self.table_view.setColumnWidth(3, 150)
self.table_view.setColumnWidth(4, 160)
self.table_view.setColumnWidth(5, 165)
def set_table_edit_trigger(self):
""" 设置表格是否可编辑 """
self.table_view.setEditTriggers(QAbstractItemView.NoEditTriggers)
def set_table_select(self):
""" 设置单元格选中模式 """
self.table_view.setSelectionBehavior(QAbstractItemView.SelectItems)
def set_table_select_mode(self):
""" 单个选中和多个选中的设置 """
self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)
self.table_view.doubleClicked.connect(self.get_table_item)
self.table_view.clicked.connect(self.get_cell_tip)
def get_cell_tip(self):
""" 设置单元格提示信息 """
contents = self.table_view.currentIndex().data()
QToolTip.showText(QCursor.pos(), contents)
def set_table_header_visible(self):
""" 设置表头的显示与隐藏 """
self.table_view.verticalHeader().setVisible(True)
self.table_view.horizontalHeader().setVisible(True)
def get_table_item(self):
"""获取表格中的数据"""
# row = self.table_view.currentIndex().row() # 获取所在行数
column = self.table_view.currentIndex().column() # 获取所在列数
contents = self.table_view.currentIndex().data() # 获取数据
# QToolTip.showText(QCursor.pos(), contents)
clipboard = qApp.clipboard() # 获取剪贴板
clipboard.setText(contents)
self.copy_tips1.setText("已复制" + self.column_name[column] + ": ")
self.copy_tips2.setText(contents)
self.copy_tips2.setStyleSheet("color:red")
def set_table_header_font_color(self):
""" 对表头文字的字体、颜色进行设置 """
self.table_view.horizontalHeader().setFont(QFont("Verdana", 13, QFont.Bold))
# self.table_view.horizontalHeader().setStyleSheet("") # 设置样式
def show_table_grid(self):
""" 设置表格参考线是否可见 """
self.table_view.setShowGrid(True)
def set_component(self):
self.btn_close = QPushButton("关闭")
self.btn_close.clicked.connect(self.close_window) # 连接槽函数
self.label1 = QLabel("当前共:")
self.label_users_num = QLabel(str(self.users_num))
self.label3 = QLabel("个用户! 双击单元格可复制单元格中的内容!")
self.copy_tips1 = QLabel("暂未复制任何内容!")
self.copy_tips2 = QLabel()
self.label_users_num.setStyleSheet("color:red")
self.label1.setFixedWidth(42)
if len(str(self.users_num)) == 1:
self.label_users_num.setFixedWidth(12)
else:
self.label_users_num.setFixedWidth(22)
self.btn_close.setFixedSize(80, 32)
self.copy_tips1.setFixedWidth(170)
def set_panel_layout(self):
""" 设置页面布局 """
v_layout = QVBoxLayout()
v_layout.addWidget(self.table_view)
h_layout1 = QHBoxLayout()
h_layout1.addWidget(self.copy_tips1)
h_layout1.addWidget(self.copy_tips2)
h_layout2 = QHBoxLayout()
h_layout2.addWidget(self.label1)
h_layout2.addWidget(self.label_users_num)
h_layout2.addWidget(self.label3)
h_layout2.addWidget(self.btn_close)
v_layout.addLayout(h_layout1)
v_layout.addLayout(h_layout2)
self.setLayout(v_layout)
def close_window(self):
self.close()
qApp.quit()
def main(self):
self.set_table_attribute()
self.set_component()
self.set_panel_layout()
if __name__ == '__main__':
user_data = [
["01", "小明", "幸福路1号", "13100000000", '[email protected]', '活泼好动,喜欢唱歌。'],
["02", "小红", "点击此处的内容将使用提示显示全部信息", "13100000001", '[email protected]', '乐观开朗,乐于助人。'],
["03", "小蓝", "幸福路3号", "13100000002", '[email protected]', '这里也是超出显示的内容:此人较懒,未填简介。'],
["04", "小黑", "幸福路4号", "13100000003", '[email protected]', '沉默寡言,爱敲代码。'],
["05", "小白", "幸福路5号", "13100000004", '[email protected]', '积极向上,喜欢发呆。']
]
app = QApplication(sys.argv)
tp = QTableViewPanel(user_data)
tp.show()
app.exit(app.exec_())
运行界面如下:
当单击某个单元格时会使用气泡的样式去显示完整的信息:
由于设置了垂直滚动条,可拖动滚动条显示余下的内容。笔者这里测试数据只写了5条,所以显示的内容也是5条:
笔者在代码中设置了双击单元格完成单元格数据的复制操作,复制的文本内容以红色字体表示,双击不同的单元格会替换掉剪贴板中的内容,只会保留最近复制的内容。具体显示如下:
最后
QTableView是一个控件,与之对应的还有QTableWidget(表格布局),也能实现显示出表格样式的界面效果。笔者这里使用的是手写的测试数据。可以通过后端接口去获取数据库的数据,这里就不做演示了。希望对大家有所帮助,同时也欢迎大家交流探讨,共同学习!