Remove duplicate entries from QListWidget?
-
Hello,
I'm writing a program that will involve creating a ListWidget. This list will only include file URLs. The only way user will be able to enter URLs is by clicking the "Browse" button and selecting multiple files. It is possible to import the same file twice, and the URL would appear on the list twice as well. In order to avoid future errors, I want to automatically remove any possible duplicates from the list. I did this with the following code, however, I have a feeling like it's not the most efficient solution:
def browse_func(self): url = QFileDialog.getOpenFileNames(self, "Open a file", "", "All Files(*)::*txt",) for i in url[0]: self.list_widget.addItem(i) items = [] for i in range(self.list_widget.count()): items.append(self.list_widget.item(i).text()) unique_items_set = set(items) self.list_widget.clear() for i in unique_items_set: self.list_widget.addItem(i)
Here's my logic: add items to Qlist -> retrieve all entries into python list -> convert that list into a set (remove duplicates) -> clear QList -> add items from existing set into QList.
There should be some method that would do it more efficiently, but I couldn't find it.
Let me know if you need more details in order to understand the problem. I'm still new to python and PyQT5, and it's the first time asking for help in the forum.
Thank you!
-
@Sebastian1993 said in Remove duplicate entries from QListWidget?:
(item, Qt::MatchFixedString | Qt::MatchCaseSensitive)
My bad, that bit is C++ (I used to do Python, now doing C++). You should know that will be the following in Python (you will come across C++ examples all the time):
(item, Qt.MatchFixedString | Qt.MatchCaseSensitive)
plus something like
from PySide2.QtCore import Qt
at the head of your file, which you'll need for many things Qt.
Also (I think!) I corrected
addItem(i)
toaddItem(item)
. If what you pasted is verbatim, you're missing an extra indent on that line. -
@Sebastian1993 Why not checking whether an URL is already in the list and only add it if not?
-
@Sebastian1993
As @jsulm says. If you want to reduce the number of lines of code to the minimum of 3 lines, at the possible expense of a tiny bit of efficiency (which won't be noticeable unless you have loads of items), you might go:for item in url[0]: if not self.list_widget.findItems(item, Qt.MatchFixedString | Qt.MatchCaseSensitive): # edit: corrected self.list_widget.addItem(item)
As it stands with your code using
getOpenFileNames()
, since that only allows picking from one directory there won't be any duplicates anyway. -
@jsulm The program will work without this feature, but I still want to add it as it's a good experience for me
@JonB I'm trying to implement your code but doesn't work, getting red highlights there:
(item, Qt::MatchFixedString | Qt::MatchCaseSensitive)
Is there anything that needs to be imported first?
-
@Sebastian1993 You misunderstood my reply. What I meant is: you can check whether an URL is already in the list and only add it if not.
-
@Sebastian1993 said in Remove duplicate entries from QListWidget?:
getting red highlights there
You should post the error...
-
@jsulm ahh I see what you mean, sorry my bad!
here's the code I'm putting in:
def browse_func(self): url = QFileDialog.getOpenFileNames(self, "Open a file", "", "All Files(*)::*txt",) for item in url[0]: if not self.list_widget.findItems(item, Qt::MatchFixedString | Qt::MatchCaseSensitive): self.list_widget.addItem(item)
and error is simply:
SyntaxError: invalid syntax
adding a screenshot in case it helps
-
@Sebastian1993 said in Remove duplicate entries from QListWidget?:
(item, Qt::MatchFixedString | Qt::MatchCaseSensitive)
My bad, that bit is C++ (I used to do Python, now doing C++). You should know that will be the following in Python (you will come across C++ examples all the time):
(item, Qt.MatchFixedString | Qt.MatchCaseSensitive)
plus something like
from PySide2.QtCore import Qt
at the head of your file, which you'll need for many things Qt.
Also (I think!) I corrected
addItem(i)
toaddItem(item)
. If what you pasted is verbatim, you're missing an extra indent on that line. -
@JonB ahh here we go it worked now! thanks a lot!
i imported this in the beginning:
from PyQt5.QtCore import Qt
-
@Denni-0 That's exactly what I wanted initially, but I couldn't come up with the code for that. The reason is that when I'm clicking "Browse" button and selecting files, I'm adding values to the QListWidget. And if I click "Browse" again to add some more files, I have to run a check whether files are already existing in the QListWidget, which I can only do by accessing entries from QListWidet.
If you have a solution, you're more than welcome to share it
-
@Sebastian1993
You have chosen to use a QListWidget:QListWidget
is a convenience class that provides a list view similar to the one supplied byQListView
, but with a classic item-based interface for adding and removing items.QListWidget
uses an internal model to manage eachQListWidgetItem
in the list.For a more flexible list view widget, use the
QListView
class with a standard model.It has its own internal model, and you have to use that. This approach will require copying data between its model and a representation you might make in your own code, where as @Denni-0 says you may prefer to do your list manipulation.
If you used a
QListView
you could set its model to, say, a QStringListModel. That is within the Qt domain. Or, you could supply a custom model and behaviour in Python code.