[Python] list of checkboxes working in an unusual way

Discussão em 'Python' iniciado por Stack, Março 7, 2025.

  1. Stack

    Stack Membro Participativo

    Im trying to create a list of checkboxes, where the RunAllTest is checked by default. when I check any other multi-select checkbox, the RunAllTest will be unchecked and when i check RunAllTest, all other multi-select checkbox should get unchecked.

    Challenge: checking RunAllTest only works when i click on the checkbox not on the label checking on other items only works when i click on the label not on the checkbox

    I tried using using pressed which works on both checkbox and text label but it ignores the logic

    please help me solve this behavior, either all item should respond to clicking/pressing on checkbox or on the label

    code

    import sys
    from PyQt6.QtCore import Qt, QThreadPool
    from PyQt6.QtGui import QStandardItemModel, QStandardItem
    from PyQt6.QtWidgets import (
    QApplication,
    QComboBox,
    QLabel,
    QMainWindow,
    QMessageBox,
    QVBoxLayout,
    QAbstractItemView,
    QListView,
    QWidget,
    )


    class MainWindow(QMainWindow):
    def __init__(self):
    super().__init__()

    self.threadpool = QThreadPool.globalInstance()
    self.crawl = None
    self.current_browser = None
    self.driver = None
    self.show_error_popup = True
    self.error_popup_response = None

    self.setWindowTitle("APP_NAME")
    self.layout = QVBoxLayout()

    self.ui_catg_names = QComboBox()
    self.ui_catg_names.setModel(QStandardItemModel(self))
    self.ui_catg_names.setView(QListView(self))
    self.ui_catg_names.view().setSelectionMode(
    QAbstractItemView.SelectionMode.MultiSelection
    )
    # self.ui_catg_names.view().pressed.connect(self.handle_item_pressed_or_clicked)
    self.ui_catg_names.view().clicked.connect(self.handle_item_pressed_or_clicked)
    self.ui_catg_names.setEditable(True)
    self.ui_catg_names.lineEdit().setReadOnly(True)
    self.ui_catg_names.lineEdit().setPlaceholderText("Select Categories")
    self.layout.addWidget(QLabel("Select Test Categories:"))
    self.layout.addWidget(self.ui_catg_names)

    catgnames = self.get_catg_names()
    self.set_catg_names(["Run All Tests"] + sorted(catgnames))
    # Assuming "Run All Tests" is the first item
    run_all_item = self.ui_catg_names.model().item(0)
    if run_all_item and run_all_item.text() == "Run All Tests":
    run_all_item.setCheckState(Qt.CheckState.Checked)

    # Create a central widget and set the layout
    central_widget = QWidget()
    central_widget.setLayout(self.layout)
    self.setCentralWidget(central_widget)

    def handle_item_pressed_or_clicked(self, index):
    item = self.ui_catg_names.model().itemFromIndex(index)
    if not item:
    return

    # Toggle check state for "Run All Tests"
    if item.text() == "Run All Tests":
    if item.checkState() == Qt.CheckState.Checked:
    self.select_all_items(False)
    item.setCheckState(
    Qt.CheckState.Checked
    ) # Keep "Run All Tests" checked
    else:
    item.setCheckState(Qt.CheckState.Unchecked)
    else:
    # Toggle check state for individual items
    if item.checkState() == Qt.CheckState.Checked:
    item.setCheckState(Qt.CheckState.Unchecked)
    else:
    item.setCheckState(Qt.CheckState.Checked)

    # Uncheck "Run All Tests" if any other item is checked
    run_all_item = self.ui_catg_names.model().item(0)
    if run_all_item and run_all_item.text() == "Run All Tests":
    run_all_item.setCheckState(Qt.CheckState.Unchecked)

    self.update_text()

    def select_all_items(self, check):
    for index in range(1, self.ui_catg_names.model().rowCount()):
    item = self.ui_catg_names.model().item(index)
    item.setCheckState(
    Qt.CheckState.Checked if check else Qt.CheckState.Unchecked
    )

    def update_text(self):
    selected_items = []
    for index in range(self.ui_catg_names.model().rowCount()):
    item = self.ui_catg_names.model().item(index)
    if item.checkState() == Qt.CheckState.Checked:
    selected_items.append(item.text())
    self.ui_catg_names.lineEdit().setText(", ".join(selected_items))

    def add_items(self, items):
    for item_text in items:
    item = QStandardItem(item_text)
    item.setFlags(Qt.ItemFlag.ItemIsUserCheckable | Qt.ItemFlag.ItemIsEnabled)
    item.setData(Qt.CheckState.Unchecked, Qt.ItemDataRole.CheckStateRole)
    self.ui_catg_names.model().appendRow(item)

    def get_selected_items(self):
    selected_items = []
    for index in range(self.ui_catg_names.model().rowCount()):
    item = self.ui_catg_names.model().item(index)
    if item.checkState() == Qt.CheckState.Checked:
    item_text = item.text()
    if item_text != "Run All Tests":
    selected_items.append(item_text)
    return selected_items

    def on_crawl_error(self, error_info):
    global POPUP_RESPONSE
    url, e = error_info
    POPUP_RESPONSE = QMessageBox.critical(
    self,
    repr(e),
    f"Error while crawling {url}\n(Ignore will prevent this popup for the rest of the run)",
    buttons=QMessageBox.StandardButton.Retry
    | QMessageBox.StandardButton.Ignore
    | QMessageBox.StandardButton.Abort,
    )
    print("COMPLETE on_crawl_error() with", POPUP_RESPONSE)

    def stop_test(self):
    if "process" in locals():
    self.process.stop()
    del self.process
    self.exit_app()

    def exit_app(self):
    if self.driver:
    self.driver.quit()
    sys.exit()

    def closeEvent(self, event):
    self.stop_test()
    event.accept()

    def get_catg_names(self):
    return ["test1", "test2", "test3"]

    def set_catg_names(self, catg_names):
    self.ui_catg_names.clear()
    self.add_items(catg_names)


    if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec())



    using python v3.11 and pyqt6 v6.8.1

    Continue reading...

Compartilhe esta Página