PyQT : How to activate a command link button when at least one element of treeview is checked ?



  • Hello,
    I want to activate command link button if at least one element is checked in a treeview.

    I tried this method but it is not working well :

    def activate_launch_button(self):
    
        model = self.scenarios.model()
        checked_indexes = model.match(model.index(0, 0), QtCore.Qt.CheckStateRole,QtCore.Qt.Checked, -1,QtCore.Qt.MatchExactly | QtCore.Qt.MatchRecursive)
        print checked_indexes
        if checked_indexes != []:
            self.launch_btn.setEnabled(True)
    

    The problem with this method is the button is activated only after closing the window. I don't understand why. For caling this method I put it in two methods :

    def show(self):
        self.project.load()
        if self.project.tranus_project:
            self.tranus_folder.setText(self.project.tranus_project.path)
        self.activate_launch_button()
        self.launch_options_TRANUS()
        super(OptionsTRANUSDialog, self).show()
    
    def select_tranus_folder(self):
    
        folder = QtGui.QFileDialog.getExistingDirectory(self, "Select directory")
        if folder:
            self.tranus_folder.setText(folder)
            if not self.project.load_tranus_folder(folder):
                self.tranus_folder.setText('')
            self.reload_scenarios()
            self.activate_launch_button()
    

    I really want that the command link button should be activated when at least one element of treeview is checked and to be inactive if there is no element checked.

    Thanks.


  • Moderators

    @EJWA Connect a slot to http://doc.qt.io/qt-5/qabstractitemview.html#activated and call your function there



  • I'm awful at Python so I'll just describe what I'd do.

    • add an integer private variable to the class that counts the items checked and initialise to 0 (int countCheck=0;).
    • define a role that will save previous check information (probably something like Qt::UserRole + Qt::CheckStateRole)
    • connect a slot to the dataChanged signal of the model
    • in the slot put something like (sorry if it's C++)
    void dataChangedSlot(const QModelIndex& index){
    if(index.data(Qt::CheckStateRole).toInt() != index.data(Qt::UserRole + Qt::CheckStateRole).toInt()){
    if(index.data(Qt::CheckStateRole).toInt()!=Qt::Unchecked){
    ++countCheck;
    model->setData(index,index.data(Qt::CheckStateRole),Qt::UserRole + Qt::CheckStateRole);
    }
    else{
    --countCheck;
    model->setData(index,QVariant(),Qt::UserRole + Qt::CheckStateRole);
    }
    launch_btn->setEnabled(countCheck>0);
    }
    }
    


  • @jsulm Hello, thank you for your reply.

    I am sorry but my item is a QStandardItem so I cannot use the method activated of QAbstractItemView.



  • Finally, I found a partial solution to my problem, I used the signal itemChanged http://pyqt.sourceforge.net/Docs/PyQt4/qstandarditemmodel.html#itemChanged

    def activate_launch_button(self):
    
        model = self.scenarios.model()
        model.itemChanged.connect(self.check_configure)
    
    
    def check_configure(self):
        self.launch_btn.setEnabled(True)
    

    It activates the button when there is one element is checked however when I uncheck all, the button doesn't become inactive. How can I solve this issue ?


  • Lifetime Qt Champion

    Hi,

    Do it like @VRonin suggested. Keep a counter and increment/decrement it when an item is changed.



  • Hello,

    Sorry, but I dont' understand really C++. If I understand, I must redefine the method setData ??

    I will try to understand.



  • Final solution, it works very well. Thanks to @SGaist and @VRonin :

    def activate_launch_button(self):
    
        model = self.scenarios.model()
        model.itemChanged.connect(self.check_configure)
    def check_configure(self,item):
    
            model = self.scenarios.model()
            index = model.indexFromItem(item)
    
            if index.data(QtCore.Qt.CheckStateRole) != index.data(QtCore.Qt.UserRole + QtCore.Qt.CheckStateRole):
    
                if index.data(QtCore.Qt.CheckStateRole)!= QtCore.Qt.Unchecked :
    
                    self.count_check+=1
                    model.setData(index,index.data(QtCore.Qt.CheckStateRole),QtCore.Qt.UserRole + QtCore.Qt.CheckStateRole)
    
                else :
    
                    self.count_check-=1
                    model.setData(index,index.data(QtCore.Qt.CheckStateRole),QtCore.Qt.UserRole + QtCore.Qt.CheckStateRole)
                    print self.count_check
    
                self.launch_btn.setEnabled(self.count_check>0)
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.