How to arrange the filtered QListwidget items in the following order,
For example, In My Program, my search term is "I" , I want to arrange item starts with "I" ("India", "Iceland", "Iran") , then item containing anywhere ("America", "China", "Fiji","Russia") , finally items end with search term "I" ("Brunei", "Mali")
import sys
from PyQt5.QtWidgets import QApplication,QWidget,QListWidget,QLineEdit,QVBoxLayout
from PyQt5.QtCore import Qt,QEvent
items = ["America","canada","Mali","India","Russia", "Fiji","Nepal","Iran","China","Japan","IceLand","Brunei"]
class Listwidget(QWidget):
def __init__(self):
super(). __init__()
self.setWindowTitle("List Box Samples")
self.le = QLineEdit()
self.le.textChanged.connect(self.func_textchanged)
self.lb_master = QListWidget()
self.lb_search = QListWidget()
vbox = QVBoxLayout(self)
vbox.addWidget(self.le)
vbox.addWidget(self.lb_search)
self.lb_master.addItems(items)
self.lb_search.addItems(items)
self.le.setFocus()
self.le.installEventFilter(self)
def eventFilter(self, source,event):
if event.type() == QEvent.KeyPress and source is self.le:
if event.key() == Qt.Key_Backspace:
if len(self.le.text()) == 0:
self.fun_normal()
return super(Listwidget,self).eventFilter(source,event)
def fun_normal(self):
self.lb_search.clear()
if normal_count > 0:
for item in item_normal:
self.lb_search.addItem(item.text())
def func_search(self):
self.lb_search.clear()
if search_count > 0:
for item in item_anywhere:
self.lb_search.addItem(item.text())
def func_textchanged(self):
global item_normal,item_anywhere,search_count,normal_count
item_normal = self.lb_master.findItems("*",Qt.MatchWildcard)
item_anywhere = self.lb_master.findItems(self.le.text(), Qt.MatchContains)
normal_count = len(item_normal)
search_count = len(item_anywhere)
self.func_search()
if __name__ == "__main__":
app = QApplication(sys.argv)
win = Listwidget()
win.show()
sys.exit(app.exec_())
There are few ways to do go about what you are trying to acheive. One is to sort the list based on a key.
In your case, it could be
item_anywhere.sort(key=lambda item: item.text().lower().find(self.le.text()))
Output:
['India', 'Iran', 'IceLand', 'Fiji', 'China', 'Mali', 'America', 'Russia', 'Brunei']
As you can see there is a small problem with this approach, that is, "Mali" is in the middle of the list and not towards the end.
The only approach I could think of right now is to use filter
function.
Below are the steps I followed:
find
method to find the strings (you have already done this part).I
or whatever the search text is.I
. def func_textchanged(self):
search_text = self.le.text().lower()
item_anywhere = self.lb_master.findItems(search_text, Qt.MatchContains)
start_list = list(filter(lambda item: item.text().lower().startswith(search_text), item_anywhere))
start_text = [x.text().lower() for x in start_list]
def bw_filter(item):
# checks if the letter is between the start and end letter, then checks if it already exists in start_list
item_text = item.text().lower()
return search_text in item_text[1:-1] and item_text not in start_text
bw_lst = list(filter(bw_filter, item_anywhere))
bw_lst.sort(key=lambda item: item.text().lower().find(search_text)) # sort it based on index
bw_text = [x.text().lower() for x in bw_lst]
def end_filter(item):
# checks if the string ends with search string, then checks if it already exists in
# start_list and between list
item_text = item.text().lower()
return item_text.endswith(search_text) and item_text.lower() not in start_text and item_text not in bw_text
end_lst = list(filter(end_filter, item_anywhere))
self.lb_search.clear()
for item in start_list + bw_lst + end_lst: # concatenate list
self.lb_search.addItem(item.text())
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.