目录
效果:
代码:
使用:
QListWidget分页多选控件主要是应对有很多的选项,从中选择需要的某几项,并将选择的结果传递给其它控件或其它窗体
导入需要的包
- import sys,math
- from PyQt5 import QtCore,QtWidgets
- from typing import Dict,Any,List
分页QListWidget多选控件
- class MultiChoicePageListWidget(QtWidgets.QWidget):
- sinout_signal = QtCore.pyqtSignal(object)
- def __init__(self):
- super().__init__()
- self.init_data()
- self.init_ui()
- def init_data(self):
- self.whole_left_list: List = []
- self.whole_right_list: List = []
- self.origin_right_list: List = []
- self.current_right_list: List = []
- self.current_left_list: List = []
- self.single_page_count: int = 10
- self.left_total_page_count: int = 0
- self.left_total_row_count: int = 0
- self.left_current_page_number: int = 1
- self.right_total_page_count: int = 0
- self.right_total_row_count: int = 0
- self.right_current_page_number: int = 1
- pass
- def init_ui(self):
- check_submit_btn = QtWidgets.QPushButton('确认提交')
- check_submit_btn.clicked.connect(self.check_submit_btn_clicked)
- layout_checksubmit = QtWidgets.QHBoxLayout()
- layout_checksubmit.addStretch(1)
- layout_checksubmit.addWidget(check_submit_btn)
- # 左侧 start
- tip_left_query_label = QtWidgets.QLabel('模糊查询')
- self.left_query_lineedit = QtWidgets.QLineEdit()
- left_query_btn = QtWidgets.QPushButton('查询')
- left_query_btn.clicked.connect(self.left_query_btn_clicked)
- left_reset_btn = QtWidgets.QPushButton('重置')
- left_reset_btn.clicked.connect(self.left_reset_btn_clicked)
- layout_left_control = QtWidgets.QGridLayout()
- layout_left_control.addWidget(tip_left_query_label,0,0,1,1)
- layout_left_control.addWidget(self.left_query_lineedit,0,1,1,3)
- layout_left_control.addWidget(left_query_btn,1,0,1,2)
- layout_left_control.addWidget(left_reset_btn,1,2,1,2)
- left_pre_btn = QtWidgets.QPushButton('<<')
- left_pre_btn.clicked.connect(self.left_pre_btn_clicked)
- left_next_btn = QtWidgets.QPushButton('>>')
- left_next_btn.clicked.connect(self.left_next_btn_clicked)
- self.left_page_lineedit = QtWidgets.QSpinBox()
- left_go_btn = QtWidgets.QPushButton('前往')
- left_go_btn.clicked.connect(self.left_go_btn_clicked)
- self.left_total_page_label = QtWidgets.QLabel('共0页')
- self.left_total_row_label = QtWidgets.QLabel('共0条')
- self.left_current_page_label = QtWidgets.QLabel('第1页')
- layout_left_up = QtWidgets.QHBoxLayout()
- layout_left_up.addWidget(left_pre_btn)
- layout_left_up.addWidget(left_next_btn)
- layout_left_up.addWidget(self.left_page_lineedit)
- layout_left_up.addWidget(left_go_btn)
- layout_left_up.addWidget(self.left_total_page_label)
- layout_left_up.addWidget(self.left_total_row_label)
- layout_left_up.addWidget(self.left_current_page_label)
- self.left_content_list_widget = QtWidgets.QListWidget()
- self.left_content_list_widget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
- layout_left = QtWidgets.QVBoxLayout()
- layout_left.addLayout(layout_left_control)
- layout_left.addLayout(layout_left_up)
- layout_left.addWidget(self.left_content_list_widget)
- # 左侧 end
- # 中间 start
- add_btn = QtWidgets.QPushButton('添加>>')
- add_btn.clicked.connect(self.add_btn_clicked)
- delete_btn = QtWidgets.QPushButton('<<删除')
- delete_btn.clicked.connect(self.delete_btn_clicked)
- clear_btn = QtWidgets.QPushButton('清空')
- clear_btn.clicked.connect(self.clear_btn_clicked)
- layout_center = QtWidgets.QVBoxLayout()
- layout_center.addStretch(1)
- layout_center.addWidget(add_btn)
- layout_center.addWidget(delete_btn)
- layout_center.addWidget(clear_btn)
- layout_center.addStretch(1)
- # 中间 end
- # 右侧 start
- tip_right_query_label = QtWidgets.QLabel('模糊查询')
- self.right_query_lineedit = QtWidgets.QLineEdit()
- right_query_btn = QtWidgets.QPushButton('查询')
- right_query_btn.clicked.connect(self.right_query_btn_clicked)
- right_reset_btn = QtWidgets.QPushButton('重置')
- right_reset_btn.clicked.connect(self.right_reset_btn_clicked)
- right_origin_btn = QtWidgets.QPushButton('回到初始')
- right_origin_btn.clicked.connect(self.right_origin_btn_clicked)
- layout_right_control = QtWidgets.QGridLayout()
- layout_right_control.addWidget(tip_right_query_label, 0, 0, 1, 2)
- layout_right_control.addWidget(self.right_query_lineedit, 0, 1, 1, 4)
- layout_right_control.addWidget(right_query_btn, 1, 0, 1, 2)
- layout_right_control.addWidget(right_reset_btn, 1, 2, 1, 2)
- layout_right_control.addWidget(right_origin_btn,1,4,2,2)
- right_pre_btn = QtWidgets.QPushButton('<<')
- right_pre_btn.clicked.connect(self.right_pre_btn_clicked)
- right_next_btn = QtWidgets.QPushButton('>>')
- right_next_btn.clicked.connect(self.right_next_btn_clicked)
- self.right_page_lineedit = QtWidgets.QSpinBox()
- right_go_btn = QtWidgets.QPushButton('前往')
- right_go_btn.clicked.connect(self.right_go_btn_clicked)
- self.right_total_page_label = QtWidgets.QLabel('共0页')
- self.right_total_row_label = QtWidgets.QLabel('共0条')
- self.right_current_page_label = QtWidgets.QLabel('第1页')
- layout_right_up = QtWidgets.QHBoxLayout()
- layout_right_up.addWidget(right_pre_btn)
- layout_right_up.addWidget(right_next_btn)
- layout_right_up.addWidget(self.right_page_lineedit)
- layout_right_up.addWidget(right_go_btn)
- layout_right_up.addWidget(self.right_total_page_label)
- layout_right_up.addWidget(self.right_total_row_label)
- layout_right_up.addWidget(self.right_current_page_label)
- self.right_content_list_widget = QtWidgets.QListWidget()
- self.right_content_list_widget.setSelectionMode(QtWidgets.QAbstractItemView.MultiSelection)
- layout_right = QtWidgets.QVBoxLayout()
- layout_right.addLayout(layout_right_control)
- layout_right.addLayout(layout_right_up)
- layout_right.addWidget(self.right_content_list_widget)
- # 右侧 end
- layout_down = QtWidgets.QHBoxLayout()
- layout_down.addLayout(layout_left,5)
- layout_down.addLayout(layout_center,1)
- layout_down.addLayout(layout_right,5)
- layout = QtWidgets.QVBoxLayout()
- layout.addLayout(layout_checksubmit)
- layout.addLayout(layout_down)
- self.setLayout(layout)
- pass
- def show_error_msg(self,error_msg:str):
- QtWidgets.QMessageBox.information(
- self,
- '提示',
- error_msg,
- QtWidgets.QMessageBox.Yes
- )
- def change_page(self,director:str):
- if director == 'left':
- start_dot = (self.left_current_page_number - 1) * self.single_page_count
- end_dot = start_dot + self.single_page_count
- current_data = self.current_left_list[start_dot:end_dot]
- self.left_content_list_widget.clear()
- self.left_content_list_widget.addItems(current_data)
- self.set_current_page_label(director)
- pass
- else:
- start_dot = (self.right_current_page_number - 1) * self.single_page_count
- end_dot = start_dot + self.single_page_count
- current_data = self.current_right_list[start_dot:end_dot]
- self.right_content_list_widget.clear()
- self.right_content_list_widget.addItems(current_data)
- self.set_current_page_label(director)
- pass
- pass
- def set_current_page_label(self,director:str):
- if director == 'left':
- self.left_current_page_label.setText(f" 第{self.left_current_page_number}页")
- else:
- self.right_current_page_label.setText(f" 第{self.right_current_page_number}页")
- pass
- def left_first_set_data(self):
- self.left_total_row_count = len(self.current_left_list)
- self.left_total_page_count = math.ceil(self.left_total_row_count / self.single_page_count)
- self.left_current_page_number = 1
- self.left_page_lineedit.setRange(1, self.left_total_page_count)
- self.left_total_row_label.setText(f" 共{self.left_total_row_count}条")
- self.left_total_page_label.setText(f" 共{self.left_total_page_count}页")
- self.change_page('left')
- pass
- def left_query_btn_clicked(self):
- query_str = self.left_query_lineedit.text()
- query_str = query_str.strip()
- if len(query_str)<=0:
- self.show_error_msg('请输入查询内容')
- return
- res_list = []
- for item in self.whole_left_list:
- if query_str in item:
- res_list.append(item)
- self.current_left_list = res_list
- self.left_first_set_data()
- pass
- def left_reset_btn_clicked(self):
- self.left_query_lineedit.setText('')
- self.current_left_list = self.whole_left_list
- self.left_first_set_data()
- pass
- def left_pre_btn_clicked(self):
- if self.left_current_page_number <= 1:
- self.show_error_msg('已经是首页')
- return
- self.left_current_page_number -= 1
- self.change_page('left')
- pass
- def left_next_btn_clicked(self):
- if self.left_current_page_number >= self.left_total_page_count:
- self.show_error_msg('已经在末页')
- return
- self.left_current_page_number += 1
- self.change_page('left')
- pass
- def left_go_btn_clicked(self):
- go_page = self.left_page_lineedit.value()
- go_page_int = int(go_page)
- if go_page_int <= 0 or go_page_int > self.left_total_page_count:
- self.show_error_msg('输入的页码超出范围')
- return
- self.left_current_page_number = go_page_int
- self.change_page('left')
- pass
- def add_btn_clicked(self):
- selected_items = self.left_content_list_widget.selectedItems()
- if len(selected_items)<=0:
- self.show_error_msg('请在左侧选择要添加的项')
- return
- text_list = [i.text() for i in selected_items]
- text_list.extend(self.current_right_list)
- right_text_set = set(text_list)
- self.current_right_list = list(right_text_set)
- self.right_first_set_data()
- pass
- def delete_btn_clicked(self):
- selected_items = self.right_content_list_widget.selectedItems()
- if len(selected_items)<=0:
- self.show_error_msg('请在右侧选择要删除的项')
- return
- text_list = [i.text() for i in selected_items]
- right_text_list = []
- for item in self.current_right_list:
- if item in text_list:
- continue
- right_text_list.append(item)
- self.current_right_list = right_text_list
- self.right_first_set_data()
- pass
- def clear_btn_clicked(self):
- self.current_right_list = []
- self.right_first_set_data()
- pass
- def right_first_set_data(self):
- self.right_total_row_count = len(self.current_right_list)
- self.right_total_page_count = math.ceil(self.right_total_row_count / self.single_page_count)
- self.right_current_page_number = 1
- self.right_page_lineedit.setRange(1, self.right_total_page_count)
- self.right_total_row_label.setText(f" 共{self.right_total_row_count}条")
- self.right_total_page_label.setText(f" 共{self.right_total_page_count}页")
- self.change_page('right')
- pass
- def right_query_btn_clicked(self):
- query_str = self.right_query_lineedit.text()
- query_str = query_str.strip()
- if len(query_str) <= 0:
- self.show_error_msg('请输入查询内容')
- return
- self.whole_right_list = self.current_right_list
- res_list = []
- for item in self.current_right_list:
- if query_str in item:
- res_list.append(item)
- self.current_right_list = res_list
- self.right_first_set_data()
- pass
- def right_reset_btn_clicked(self):
- self.current_right_list = self.whole_right_list
- self.right_query_lineedit.setText('')
- self.right_first_set_data()
- pass
- def right_pre_btn_clicked(self):
- if self.right_current_page_number <= 1:
- self.show_error_msg('已经是首页')
- return
- self.right_current_page_number -= 1
- self.change_page('right')
- pass
- def right_next_btn_clicked(self):
- if self.right_current_page_number >= self.right_total_page_count:
- self.show_error_msg('已经在末页')
- return
- self.right_current_page_number += 1
- self.change_page('right')
- pass
- def right_go_btn_clicked(self):
- go_page = self.right_page_lineedit.value()
- go_page_int = int(go_page)
- if go_page_int <= 0 or go_page_int > self.right_total_page_count:
- self.show_error_msg('输入的页码超出范围')
- return
- self.right_current_page_number = go_page_int
- self.change_page('right')
- pass
- def right_origin_btn_clicked(self):
- self.right_query_lineedit.setText('')
- self.current_right_list = self.origin_right_list
- self.right_first_set_data()
- pass
- def set_data(self,data:Dict[str,Any]):
- self.origin_right_list = data['whole_right']
- self.whole_left_list = data['whole_left']
- self.whole_right_list = data['whole_right']
- self.current_left_list = data['whole_left']
- self.current_right_list = data['whole_right']
- self.left_first_set_data()
- self.right_first_set_data()
- self.left_query_lineedit.setText('')
- self.right_query_lineedit.setText('')
- pass
- def check_submit_btn_clicked(self):
- self.sinout_signal.emit(self.current_right_list)
- pass
- pass
调用QListWidget分页多选控件的容器
- class ExampleWidget(QtWidgets.QWidget):
- def __init__(self):
- super().__init__()
- self.init_ui()
- def init_ui(self):
- self.list_widget = MultiChoicePageListWidget()
- self.list_widget.sinout_signal.connect(self.list_widget_sinout_emit)
- layout = QtWidgets.QVBoxLayout()
- layout.addWidget(self.list_widget)
- self.setLayout(layout)
- pass
- def set_data(self,data:Dict[str,Any]):
- self.list_widget.set_data(data)
- pass
- def list_widget_sinout_emit(self,data:List[str]):
- print(data)
- pass
- if __name__ == '__main__':
- whole_left = ['1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','65','66']
- whole_right = ['1','2','3','4','5']
- data = {
- 'whole_left':whole_left,
- 'whole_right':whole_right
- }
- QtCore.QCoreApplication.setAttribute(QtCore.Qt.HighDpiScaleFactorRoundingPolicy.PassThrough)
- app = QtWidgets.QApplication(sys.argv)
- temp_win = ExampleWidget()
- temp_win.set_data(data)
- temp_win.show()
- app.exec()
- pass
运行:
清空右侧,并选中左侧所有包含“1”的选项:
点击“清空”,清空右侧列表;在左侧模糊查询中输入1,点击“查询”按钮;接下来选中左侧包含“1”的内容,添加到右侧
点击“确认提交”,后台接收到选中的结果
联系客服