0

I'm trying to find the checked item in a QListWidget, however, I'm not sure how to identify the one being checked because I'm not using a name for each individual checkbox. Basically, I have multiple unknown strings, which are made into checkboxes and put into a QListWidget. I am then trying to find which one of these checkboxes has been checked.

This is how I am currently making my checkboxes (but I can use another widget if it is better)

thing2 = ['asdsa', 'dasdas', 'sdasdas', 'asdsa', 'sdasdad']
for item in thing2:
    vbox.addWidget(QCheckBox(item))

and it creates an application that looks like this: vbox with multiple stacked checkboxes

However, I can't tell which checkbox is being checked (because I want to perform an action on checked items)

So far, I've tried using the QListWidget in order to better organize it, and I had originally thought I'd be able to refer to each of the items as with normal python lists, however I still wasn't able to check which checkbox was ticked.

https://github.com/yjg30737/pyqt-checkbox-file-list-widget

This is basically what I'm trying to do, picking some of the checkboxes, and have a button which allows me to delete the items, however, I haven't been able to make it work with normal text. (I checked the installed files, and I think it only works with files)

I've also tried using Model View Controller code, which was recommended to me online as it was said to be a lot easier to have it transferred onto a widget, but I found it extremely confusing (and it didn't work out) so I'd prefer not using that if its possible.

Are there any methods that I can use instead for my program to recognize state changes in ways that allow me to modify the changed items? I'm ok if it completely changes the code.

EDIT: I think my question was really confusing but below is the code I used to create the list widget. I couldn't use QCheckBox and put it directly into the QListWidget, because I don't think it accepts it, I got the following error when I tried to the code:

item = QListWidgetItem(QCheckBox("Hi"))
list_widget.addItem(item)
  PySide2.QtWidgets.QListWidgetItem(PySide2.QtGui.QIcon, str, typing.Optional[PySide2.QtWidgets.QListWidget] = None, int = PySide2.QtWidgets.QListWidgetItem.ItemType.Type)
  PySide2.QtWidgets.QListWidgetItem(typing.Optional[PySide2.QtWidgets.QListWidget] = None, int = PySide2.QtWidgets.QListWidgetItem.ItemType.Type)
  PySide2.QtWidgets.QListWidgetItem(PySide2.QtWidgets.QListWidgetItem)
  PySide2.QtWidgets.QListWidgetItem(str, typing.Optional[PySide2.QtWidgets.QListWidget] = None, int = PySide2.QtWidgets.QListWidgetItem.ItemType.Type)

So instead of using a checkbox, I used ItemIsUserCheckable.

This is a minimum reproducible example of my code:

import sys

from PySide2.QtCore import Qt
from PySide2.QtWidgets import QApplication, QComboBox, QMainWindow, QListWidget, QHBoxLayout, QListWidgetItem, QWidget, \
    QPushButton, QCheckBox
from PySide2 import QtCore, QtWidgets

app = QApplication()
widget = QListWidget()
for i in range(5):
    item = QListWidgetItem(str(i))

    item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
    item.setCheckState(QtCore.Qt.Checked)
    widget.addItem(item)
    item = QListWidgetItem(QCheckBox("Hi"))
    widget.addItem(item)

selected = []
for i in range(0, widget.count()):
    if widget.item(i).isChecked():
        selected.append(i)

widget.show()
app.exec_()

(I am trying to delete the checked item)

  • 1
    Just create a list as an instance attribute which contains all the checkboxes and iterate through it to get which ones are checked. If the names are guaranteed to be unique, you could even use a dictionary. If you instead want to use QListWidget, please provide a [mre] of your attempt in getting the items. – musicamante Aug 18 '23 at 08:05
  • Thanks for the advice! I added a minimal reproducible example – BigBrain Productions Aug 18 '23 at 14:59
  • Qt, as with most UI toolkits, is an *event driven* system, and uses an *observer pattern* that calls function when "something" happens. Your code doesn't work because you're trying to get the selected items while the program is just being started. You have to connect some signal (for instance, the `clicked` one of a button) to a function that actually gets the *currently* checked items. I strongly suggest you to look for some tutorials about the basics of Qt (including signals and slots), as it seems clear that you still need to understand how all this works. – musicamante Aug 18 '23 at 16:50

1 Answers1

-1

OnClick:

self.selected = []
for i in range(0, self.listWidget.count()):
    if(self.listWidget.item(i).isChecked()):
       self.selected.append(i)

This will return all selected IDs to selected.

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
5px
  • 131
  • 9
  • 1
    Please check your code and fix it, as it has a lot of issues, most importantly: `self.row` is empty, `checkboxes` is fundamentally unused, and `addItem()` does not accept widgets. – musicamante Aug 18 '23 at 08:43
  • Sorry, I've copied my example that worked with a TableWidget. Since OP already figured out how to add them, I'm pretty sure he could use the second snippet to access the checkboxes by reference. – 5px Aug 18 '23 at 08:45
  • I had also came across this code, but I wasn't sure how to use it because I'm not sure how to trigger it when there's a change in the checkbox statuses. I tried to put it into a function, but it didn't work for me because my checkbox didn't have the function "clicked.connect", so I had ruled it out as a possibility. Is there a way to trigger the function only when something has been clicked? Or would it be possible to create a QThread that would continuously iterate over the QListWidget? – BigBrain Productions Aug 18 '23 at 12:40
  • In the question it says that you want to check the state of all checkboxes when a delete button is clicked. Now it looks more like you want that to happen when one of the checkboxes is clicked. That doesn't make much sense. If you want to delete checked boxes immediately when the box is checked, you don't need to check the others. – mahkitah Aug 18 '23 at 13:23
  • Also, `QCheckBoxes` do emit the `clicked` signal when clicked, so you can connect to it normally. – mahkitah Aug 18 '23 at 13:24
  • So to delete a checkbox when one has been checked, would I continuously iterate through the list of QCheckboxes, and when one is clicked, I remove it from the QListWidget? – BigBrain Productions Aug 18 '23 at 14:31
  • @BigBrainProductions You're making a lot of confusion. If you use multiple QCheckBoxes, then use its signals (and, yes, QCheckBox **does** have a `clicked` signal), if you use QListWidget then use the signals for **that** widget. In any case, deleting a checkbox as soon as it's been clicked is not a good solution. – musicamante Aug 18 '23 at 16:53
  • Sorry about the confusion, do you recommend me using QCheckboxs instead of multiple items, and turning it into a checkbox with "QtCore.Qt.ItemIsUserCheckable"? I'll try and find out what my problem is so I can create a better question. – BigBrain Productions Aug 18 '23 at 18:48
  • @BigBrainProductions you're still confusing things. You cannot "turn" QListWidget items into QCheckBoxes, as they are different widgets. Using the `ItemIsUserCheckable` flag makes an item checkable, it will *look like* a checkbox, but it will not make it a different widget. I strongly urge you to read more carefully the documentation about those two widgets, the fact that they can be used for similar purposes doesn't make them identical in behavior nor implementation. QCheckBox is a *single* checkable widget (so you need many), QListWidget is a *view* that shows multiple *items*. – musicamante Aug 18 '23 at 20:42