当前位置:网站首页>PyQt5_QTableWidget分页单选右键菜单控件

PyQt5_QTableWidget分页单选右键菜单控件

2022-06-23 22:11:00 程序猿与金融与科技

目录

效果

代码 

使用


PyQt5实现QTableWidget分页,右键菜单自定义设置,集成在一个控件中,方便使用。

效果

代码 

分页表格控件代码

import sys,math
from typing import Any,List,Dict
from PyQt5 import QtCore,QtWidgets,QtGui
from PyQt5.QtCore import Qt

# 分页表格控件,单选
class PageTableWidget(QtWidgets.QWidget):
    sinout_signal = QtCore.pyqtSignal(object)
    def __init__(self):
        super().__init__()
        self.init_data()
        self.init_ui()
        pass
    def init_data(self):
        # 表格全数据 二维数组
        self.table_full_data: List[Any] = []
        # 表格右键菜单 {菜单名:索引指向}
        self.table_right_menus: Dict[str,str] = {}

        self.total_page_count: int = 0
        self.total_rows_count: int = 0
        self.current_page: int = 1
        self.single_page_rows: int = 5
        pass
    def init_ui(self):
        pre_page_btn = QtWidgets.QPushButton('上一页')
        pre_page_btn.clicked.connect(self.pre_page_btn_clicked)
        next_page_btn = QtWidgets.QPushButton('下一页')
        next_page_btn.clicked.connect(self.next_page_btn_clicked)

        tip_label_0 = QtWidgets.QLabel('第')
        self.witch_page_lineedit = QtWidgets.QLineEdit()
        self.int_validator = QtGui.QIntValidator()
        self.witch_page_lineedit.setValidator(self.int_validator)
        self.witch_page_lineedit.setMaximumWidth(20)
        tip_label_1 = QtWidgets.QLabel('页')
        go_page_btn = QtWidgets.QPushButton('前往')
        go_page_btn.clicked.connect(self.go_page_btn_clicked)
        layout_witch_page = QtWidgets.QHBoxLayout()
        layout_witch_page.addWidget(tip_label_0)
        layout_witch_page.addWidget(self.witch_page_lineedit)
        layout_witch_page.addWidget(tip_label_1)
        layout_witch_page.addWidget(go_page_btn)
        layout_witch_page.addStretch(1)

        self.total_page_count_label = QtWidgets.QLabel(f"共0页")
        self.total_rows_count_label = QtWidgets.QLabel(f"共0行")
        self.current_page_label = QtWidgets.QLabel(f"当前第0页")
        layout_pagestatus = QtWidgets.QHBoxLayout()
        layout_pagestatus.addWidget(self.total_page_count_label)
        layout_pagestatus.addWidget(self.total_rows_count_label)
        layout_pagestatus.addWidget(self.current_page_label)

        layout_top = QtWidgets.QHBoxLayout()
        layout_top.addWidget(pre_page_btn)
        layout_top.addWidget(next_page_btn)
        layout_top.addLayout(layout_witch_page)
        layout_top.addLayout(layout_pagestatus)
        layout_top.addStretch(1)

        self.target_table = QtWidgets.QTableWidget()
        self.target_table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
        self.target_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        self.target_table.setContextMenuPolicy(Qt.CustomContextMenu)
        self.target_table.customContextMenuRequested.connect(self.target_table_rightclicked_menu)

        layout = QtWidgets.QVBoxLayout()
        layout.addLayout(layout_top)
        layout.addWidget(self.target_table)
        self.setLayout(layout)
        pass
    def set_table_init_data(self,data:Dict[str,Any]):
        '''设置表头、右键菜单等初始化内容'''
        headers:List[str] = data['headers']
        self.table_right_menus = data['table_right_menus']

        self.target_table.setColumnCount(len(headers))
        self.target_table.setHorizontalHeaderLabels(headers)
        pass
    def set_table_full_data(self,data:Dict[str,str]):
        '''表格全数据'''
        self.table_full_data = data
        self.total_rows_count = len(data)
        self.total_page_count = math.ceil(self.total_rows_count/self.single_page_rows)
        self.current_page = 1

        self.int_validator.setRange(1,self.total_page_count)

        self.total_page_count_label.setText(f"共{self.total_page_count}页")
        self.total_rows_count_label.setText(f"共{self.total_rows_count}行")
        self.caculate_current_show_data()
        pass
    def setting_current_pagestatus_label(self):
        self.current_page_label.setText(f"当前第{self.current_page}页")
        pass
    def caculate_current_show_data(self):
        '''计算当前要显示的数据'''
        start_dot = (self.current_page-1)*self.single_page_rows
        end_dot = start_dot + self.single_page_rows
        current_data = self.table_full_data[start_dot:end_dot]
        self.fill_table_content(current_data)
        self.setting_current_pagestatus_label()
        pass
    def fill_table_content(self,data:List[Any]):
        self.target_table.clearContents()
        self.target_table.setRowCount(len(data))
        for r_i,r_v in enumerate(data):
            for c_i,c_v in enumerate(r_v):
                cell = QtWidgets.QTableWidgetItem(c_v)
                self.target_table.setItem(r_i, c_i, cell)
                pass
            pass
        self.target_table.resizeColumnsToContents()
        pass
    def go_page_btn_clicked(self):
        '''前往按钮点击'''
        input_page = self.witch_page_lineedit.text()
        input_page = input_page.strip()
        if not input_page:
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '请输入要跳转的页码',
                QtWidgets.QMessageBox.Yes
            )
            return
        input_page = int(input_page)
        if input_page<0 or input_page>self.total_page_count:
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '输入的页码超出范围',
                QtWidgets.QMessageBox.Yes
            )
            return
        self.current_page = input_page
        self.caculate_current_show_data()
        pass
    def pre_page_btn_clicked(self):
        '''上一页按钮点击'''
        if self.current_page<=1:
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '已经是首页',
                QtWidgets.QMessageBox.Yes
            )
            return
        self.current_page -= 1
        self.caculate_current_show_data()
        pass
    def next_page_btn_clicked(self):
        '''下一页按钮点击'''
        if self.current_page>=self.total_page_count:
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '已经是最后一页',
                QtWidgets.QMessageBox.Yes
            )
            return
        self.current_page += 1
        self.caculate_current_show_data()
        pass
    def target_table_rightclicked_menu(self,pos):
        '''表格右键菜单'''
        selectedItems = self.target_table.selectedItems()
        if len(selectedItems)<=0:
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '请选择要操作的行',
                QtWidgets.QMessageBox.Yes
            )
            return
        if not self.table_right_menus:
            QtWidgets.QMessageBox.information(
                self,
                '提示',
                '没有右键菜单',
                QtWidgets.QMessageBox.Yes
            )
            return

        menu = QtWidgets.QMenu()
        menu_item_list = []
        for item in self.table_right_menus.keys():
            temp_item = menu.addAction(item)
            menu_item_list.append(temp_item)
            pass
        current_action = menu.exec_(self.target_table.mapToGlobal(pos))
        for item in menu_item_list:
            if item == current_action:
                # 发出信号
                action_name = item.text()
                pre_res_map = {}
                pre_res_map['action_name'] = action_name
                pre_res_map['action_target'] = self.table_right_menus[action_name]
                action_res_data = [i.text() for i in selectedItems]
                pre_res_map['action_data'] = action_res_data
                self.sinout_signal.emit(pre_res_map)
                break
            pass
        pass
    pass

放置分页表格控件的容器

class Example_widget(QtWidgets.QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        pass
    def init_ui(self):
        self.setWindowTitle('表格显示示例')
        self.table = PageTableWidget()
        self.table.sinout_signal.connect(self.table_signal_recive)
        layout = QtWidgets.QVBoxLayout()
        layout.addWidget(self.table)
        self.setLayout(layout)
        pass
    def setting_data(self,data1,data2):
        self.table.set_table_init_data(data1)
        self.table.set_table_full_data(data2)
        pass
    def table_signal_recive(self,data:Dict[str,Any]):
        print(data)
        pass

使用

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)

    pre_data = {}
    pre_data['headers'] = ['编号','姓名','性别','归属']
    pre_data['table_right_menus'] = {
        '右菜1':'target_11',
        '右菜2':'target_22',
        '右菜3':'target_33'
    }

    pre_body_data = [
        ['000','林黛玉','女','红楼梦'],
        ['001','孙尚香','女','三国演义'],
        ['002','孙悟空','男','西游记'],
        ['003','刘备','男','三国演义'],
        ['004','宋江','男','水浒传'],
        ['005','贾宝玉','男','红楼梦'],
        ['006','关羽','男','三国演义'],
        ['007','张飞','男','三国演义']
    ]

    t_win = Example_widget()
    t_win.setting_data(pre_data,pre_body_data)
    t_win.show()
    sys.exit(app.exec_())
    pass

右键选择菜单点击后,该行的内容会回传到容器控件

控制台输出了容器中接收到的信息

{'action_name': '右菜1', 'action_target': 'target_11', 'action_data': ['002', '孙悟空', '男', '西游记']}
 

原网站

版权声明
本文为[程序猿与金融与科技]所创,转载请带上原文链接,感谢
https://blog.csdn.net/m0_37967652/article/details/125407181