vendredi 14 août 2020

Some PyQt5 Checkboxes are unclickable after being moved

I'm creating a to-do list where a checkbox, textbox (QLineEdit), and QComboBox (to set Priority 1, 2, etc.) are added each time the "Add Task" button is clicked. When the checkbox for each corresponding task is clicked, the task would move to the bottom of the list of tasks. Conversely, if a priority is set, then the task is moved to the top of the list of tasks.

The problem is that in certain circumstances, when I click on the checkbox, nothing happens. The signal that identifies that the checkbox state has changed is never sent. It's almost like the checkbox isn't there, even though it (or at least, the image of it) is. This problem happens if none of the priorities are set with unchecking—checking any given task works, but certain tasks cannot be unchecked. Other tasks are able to be unchecked, and sometimes if I go back to the task that couldn't be unchecked after unchecking something else, it'll be checkable again. If I were to set some tasks to have a priority and then go and try to check the checkboxes, some checkboxes won't be able to be checked at all. Again, if I were to check some other task and then go back to the task that wasn't able to be checked, it might be able to be checked this time around.

I think the error might be coming from moving the checkboxes... for some reason the functionality behind some of the checkboxes is lost going through the code. One notable thing is tabbing through the items in the GUI. Once items are moved, hitting tab will go through the items in the same order that it was originally set up in (so the cursor will essentially jump around the textboxes instead of going in order from top to bottom). Not sure if that has anything to do with the error; it's just something I've noticed. I'm don't know if this is an error within PyQt5 itself, or if it's a fixable error within the code.

import sys
from PyQt5.QtWidgets import (QWidget, QComboBox,
    QPushButton, QApplication, QLabel, QLineEdit, QTextEdit, QMainWindow, QAction, QShortcut, QCheckBox)
from PyQt5.QtGui import (QKeySequence)
from PyQt5 import QtWidgets, QtCore
from PyQt5.QtCore import pyqtSlot, QObject

class App(QMainWindow): 
    
    def __init__(self):
        super().__init__()
        self.i = 40
        self.j = 80
        self.counter = 1
        self.list_eTasks = []
        self.initUI()

    def initUI(self):
        #sets up window
        self.setWindowTitle('To-Do List')
        self.setGeometry(300, 300, 800, 855)

        #button
        self.btn1 = QPushButton("Add Task", self)
        self.btn1.clicked.connect(self.add_task_button_clicked)
        
        #close the window via keyboard shortcuts
        self.exit = QShortcut(QKeySequence("Ctrl+W" or "Ctrl+Q"), self)
        self.exit.activated.connect(self.close)

        self.show()

    @pyqtSlot()
    def add_task_button_clicked(self):
        self.label = QLabel(self)
        self.label.setText(str(self.counter))
        self.label.move(5, self.i)

        self.btn1.move(50, self.j)

        self.textbox = QLineEdit(self)
        self.textbox.resize(280, 40)

        self.checkbox = QCheckBox(self)
        self.checkbox.stateChanged.connect(self.click_box)
    
        self.combobox = QComboBox(self)
        self.combobox.addItem("No Priority")
        self.combobox.addItem("Priority 1")
        self.combobox.addItem("Priority 2")
        
        self.combobox.addItem("Priority 3")
        self.combobox.activated[str].connect(self.combobox_changed)
        
        self.obj = eTask(self.checkbox, self.textbox, self.combobox)
        self.list_eTasks.append(self.obj)


        self.textbox.show()
        self.label.show()
        self.checkbox.show()
        self.combobox.show()

        self.i += 40
        self.j += 40
        self.counter += 1
        self.sort_eTasks()

    def click_box(self, state):
        self.sort_eTasks()

    def move_everything(self, new_list):
        count = 0
        for item in new_list:
            y_value = ((40)*(count + 1))
            item.check.move(20, y_value)
            item.text.move(50, y_value)
            item.combo.move(350, y_value)
            count += 1
        return

    def combobox_changed(self, state):
        #make new list to not include any already checked off items
        for task in self.list_eTasks:
            if task.combo.currentText() == "Priority 1":
                task.priority = 1
            elif task.combo.currentText() == "Priority 2":
                task.priority = 2
            elif task.combo.currentText() == "Priority 3":
                task.priority = 3
            else:
                task.priority = 10
        self.sort_eTasks()

    def sort_eTasks(self):
        self.list_eTasks.sort(key=lambda eTask: eTask.getRank())
        self.move_everything(self.list_eTasks)
        for task in self.list_eTasks:
            print(str(task.priority) + " pos: " + str(task.check.pos()))

        print("-----------------------------------")

class eTask: 
    check = ""
    text = ""
    combo = ""
    priority = 10

    def __init__(self, c, t, co):
        self.check = c
        self.text = t
        self.combo = co
    
    def setP(self, p):
        self.priority = p

    def getRank(self):
        if self.check.isChecked():
            return self.priority + 100
        else:
            return self.priority

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())



Aucun commentaire:

Enregistrer un commentaire