目录
效果:
代码:
使用:
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”的内容,添加到右侧
点击“确认提交”,后台接收到选中的结果