Katalpa
Katalpa

Reputation: 159

(PyQt) Uncheck pushbutton from outside button's class?

A QPushButton is set 'asCheckable'. Whence toggled, a class bool is changed.
This altered bool allows a method in a different class to proceed, and upon completion of this outside method I need to return the button to its initial state, 'setChecked(False)'.

While I am able to return the class housed bool to its default state at the end of this external method, I am unable to externally access a method which un-clicks the button.

I assume its due to the arguments in the classes init, but these are necessary - and I'm wondering if there is another means to achieve the described workflow.

Related code snips below:

(command in question is distinguished at bottom of 'Class 2')

Class 1:

class shapeCSVeditor(QtGui.QDialog, QtGui.QWidget):
   valueShare = []
   rowOverride = False#  <<=== equivalent to 'override' in 'Class 2'
   def __init__(self, iface, fileName, editorType, parent=None):
       super(shapeCSVeditor, self).__init__(parent)
       self.iface = iface
       self.editorType = editorType
       self.fileName = filename
       self.pushButtonSetBase = QtGui.QPushButton(self)
       self.pushButtonSetBase.setText("Set Base Shape")
       self.pushButtonSetBase.setCheckable(True)
       self.pushButtonSetBase.toggled.connect(self.on_pushButtonSetBase_toggled)
       self.layoutHorizontal.addWidget(self.pushButtonSetBase)

   #some other things here...

   @QtCore.pyqtSlot()
   def on_pushButtonSetBase_toggled(self):
       shapeCSVeditor.rowOverride = True
       pass

   def on_BaseRow_Changed(self):
       self.pushButtonSetBase.setChecked(False)
       return 

Class 2:

class CSVModel(QtCore.QAbstractTableModel):

  # Establish inital settings and branch processes
  def __init__(self, iface, fileName, editorType, parent=None):
      super(CSVModel,self).__init__()
      self.propertiesFile = r'some file'
      self.areaStressFile = r'some other file'          
      self.iface = iface
      self.rows = []
      self.editorType = editorType
      self.loadCSV()
      self.iface.mapCanvas().selectionChanged.connect(self.addRow)

  # add rows to the TableView based on object selection(s) in Qgis.mapCanvas
  def addRow(self):
      override = shapeCSVeditor.rowOverride
      selectedFeatures = selectedLayer.selectedFeatures()
      if override:
          for feature in selectedFeatures:
              self.rows.pop(0)
              feat_Attributes = []
              feat_Attributes.extend([self.iface.activeLayer().name()+'_'+str(feature.id())])
              feat_Attributes.extend(['',]*(len(self.header)-1))
              self.beginResetModel()
              self.rows.insert(0,feat_Attributes)
              shapeCSVeditor.rowOverride = False
              self.endResetModel()

              shapeCSVeditor.on_BaseRow_Changed# <<<=== wrong-diddily!

              break

PS - if parentheticals are added to the 'shapeCSVeditor()' 3 arguments are requisite as referenced in the Button class, and if parentheticals are added to 'on_BaseRow_Changed', the return is;

TypeError: unbound method on_BaseRow_Changed() must be called with shapeCSVeditor instance as first argument (got nothing instead)

Upvotes: 1

Views: 3436

Answers (2)

Katalpa
Katalpa

Reputation: 159

class shapeCSVeditor(QtGui.QDialog, QtGui.QWidget):
    valueShare = []
    rowOverride = False
    def __init__(self, iface, fileName, editorType, parent=None):
        super(shapeCSVeditor, self).__init__(parent)
        self.iface = iface
        self.editorType = editorType
        self.fileName = fileName
        self.tableView = QtGui.QTableView(self)
        self.setWindowFlags(self.windowFlags() | QtCore.Qt.WindowStaysOnTopHint)
        self.tableData = CSVModel(self,iface,fileName,editorType)
               ^^==not implementing 'self' (shapeCSVeditor object) was the problem!
        self.tableView.setModel(self.tableData)
        ...
        self.pushButtonSetBase = QtGui.QPushButton(self)
        self.pushButtonSetBase.setText("Set Base Shape")
        self.pushButtonSetBase.setCheckable(True)
        self.pushButtonSetBase.clicked.connect(self.on_pushButtonSetBase_toggled)
        ...
    @QtCore.pyqtSlot()
    def on_pushButtonSetBase_toggled(self):
        self.rowOverride = True

    @QtCore.pyqtSlot()
    def on_BaseRow_Changed(self):
        self.rowOverride = False
        self.pushButtonSetBase.setChecked(False)

///////////////////////////////////////////////////////////////////////////////////////

class CSVModel(QtCore.QAbstractTableModel):
    def __init__(self, shapeCSVeditor, iface, fileName, editorType):
        super(CSVModel,self).__init__()
        self.propertiesFile = r'foo'
        self.areaStressFile = r'bar'
        self.tableView = shapeCSVeditor  <<== proper passing of shapeCSVeditor object! (?)
        self.iface = iface
        self.rows = []
        self.editorType = editorType
        self.loadCSV()
        self.iface.mapCanvas().selectionChanged.connect(self.addRow)

        ...

    def addRow(self):
        selectedFeatures = selectedLayer.selectedFeatures()
        if self.tableView.rowOverride:
            for feature in selectedFeatures:
                self.rows.pop(0)
                feat_Attributes = []
                feat_Attributes.extend([self.iface.activeLayer().name()+'_'+str(feature.id())])
                feat_Attributes.extend(['',]*(len(self.header)-1))
                self.beginResetModel()
                self.rows.insert(0,feat_Attributes)
                self.endResetModel()
                self.tableView.rowOverride = False
                self.tableView.on_BaseRow_Changed()

Radical. Works for the current needs. Now the question is if its proper to python 'standards'. Quite new to writing, so its possible more needs fixed.

High thanks to Plouff for the clues.

Upvotes: 0

Plouff
Plouff

Reputation: 3470

What you are doing is strange. In python, the first argument of a class method is always the object itself. So, in your:

   def on_BaseRow_Changed(self):
       self.pushButtonSetBase.setChecked(False)
       # return => This return is useless

if you don't provide an object then you can't access the pushbutton.

You didn't gave us all the code but I think you should provide your addRow with the shapeCSVeditor object that you want to update:

def addRow(self, shapeCSVObj):
   override = shapeCSVObj.rowOverride
   if override:
      for feature in selectedFeatures:
          self.rows.pop(0)
          feat_Attributes = []
          feat_Attributes.extend([self.iface.activeLayer().name()+'_'+str(feature.id())])
          feat_Attributes.extend(['',]*(len(self.header)-1))
          self.beginResetModel()
          self.rows.insert(0,feat_Attributes)
          shapeCSVObj.rowOverride = False
          self.endResetModel()

          shapeCSVObj.on_BaseRow_Changed()

          break

Somewhere you must have a shapeCSVeditor that is created. You should provide it to you outside class.

Hope this helps.

Upvotes: 1

Related Questions