1

I need to make a macro in Python.

I want to enable a QlineEdit when a QCheckBox is checked; how do I do it?

This is the code:

import os, sys, App
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

class Window(QDialog):
    def __init__(self, parent=None):
        super(Window, self).__init__(parent)
        self.fabricatorLineEdit = self.createLineEdit("fabricatorLineEdit", "fabricator")
        self.fabricatorLineEdit.setDisabled(True)

        self.chBoxFab = self.createCheckBox("chBoxFab", "Insert a alternative value to 'fabricator' key:")
        self.chBoxFab.stateChanged.connect(self.chbxStateChange(self.chBoxFab, self.fabricatorLineEdit))

        self.chBoxPrjManager = self.createCheckBox("chBoxPrjManager", "Insert a alternative value to 'Project Manager' key:")

        self.projManagerLineEdit = self.createLineEdit("projManagerLineEdit", "Project Manager")
        self.projManagerLineEdit.setDisabled(True)  
      self.chBoxPrjManager.stateChanged.connect(self.chbxStateChange(self.chBoxPrjManager , self.projManagerLineEdit))
        mainLayout = QtWidgets.QFormLayout()
        mainLayout.addRow(self.chBoxFab)
        mainLayout.addRow(self.fabricatorLineEdit)
        mainLayout.addRow(self.chBoxPrjManager)
        mainLayout.addRow(self.projManagerLineEdit)
        self.setLayout(mainLayout)

    def createLineEdit(self, objName, defaultTxt):
        lineEdit = QtWidgets.QLineEdit(self)
        lineEdit.setObjectName(objName)
        lineEdit.setText(defaultTxt)
        return lineEdit

    def createCheckBox(self, objName, objCaption):
        chBox = QtWidgets.QCheckBox(self)
        chBox.setObjectName(objName)
        chBox.setText(objCaption)
        return chBox

    def chbxStateChange(self, chBox, lineEdit):
       if chBox.isChecked:
        lineEdit.setDisabled(False)
       else:
          lineEdit.setDisabled(True)

    if __name__ == '__main__':

       import sys

       window = Window()
       result = window.exec_()

I define an event to check the state of the QCheckBox to enable the QlineEdit but it doesn't work:

    def chbxStateChange(self, chBox, lineEdit):
        if chBox.isChecked:
            lineEdit.setDisabled(False)
        else:
            lineEdit.setDisabled(True)

I understand that the problem is in the function chbxStateChange but I don't know how to resolve it.

The error:

error return without exception set Traceback (most recent call last): File "C:/Program Files/.../Python/Scripts/test.py", line 332, in window = Window() File "C:/Program Files/.../Python/Scripts/test.py", line 35, in init

self.chBoxFab.stateChanged.connect(self.chbxStateChange(self.chBoxFab, self.fabricatorLineEdit))

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Silenzio76
  • 53
  • 7
  • Change self.chBoxFab.stateChanged.connect(self.chbxStateChange(self.chBoxFab, self.fabricatorLineEdit)) to self.chBoxFab.stateChanged.connect(self.chbxStateChange(lambda: self.chBoxFab, self.fabricatorLineEdit)) – eyllanesc Jan 17 '17 at 17:23

1 Answers1

1

There are two errors in your code.

Firstly, the connect method of signals takes a callable object, but your code passes in the return value of a method (which in this case is None). So instead, you should make the connections like this:

self.chBoxFab.stateChanged.connect(
    lambda: self.chbxStateChange(self.chBoxFab,
                                 self.fabricatorLineEdit))

self.chBoxPrjManager.stateChanged.connect(
    lambda: self.chbxStateChange(self.chBoxPrjManager,
                                 self.projManagerLineEdit))

Secondly, the chbxStateChange method makes the opposite mistake of treating isChecked as an attribute (rather than calling it), meaning it will always evaluate to True. So instead, the code should look like this:

def chbxStateChange(self, chBox, lineEdit):
    if chBox.isChecked():
        lineEdit.setDisabled(False)
    else:
        lineEdit.setDisabled(True)

However, if all you want to do is toggle the enabled state of a line-edit, this code is overcomplicated. The connections can instead be made like this:

self.chBoxFab.toggled.connect(self.fabricatorLineEdit.setEnabled)
self.chBoxPrjManager.toggled.connect(self.projManagerLineEdit.setEnabled)

The toggled signal sends the button's checked state (True or False) which can then directly set the enabled state of the line-edit. (And If you wanted to the line-edit to be disabled when the button is checked, you would connect toggled to setDisabled).

If you do things this way, the chbxStateChange method is no longer needed.


(NB: the QCheckBox class inherits QAbstractButton, which is where it gets the toggled signal from).

ekhumoro
  • 115,249
  • 20
  • 229
  • 336