3

I'm building a QGIS 3.0 plugin and trying to organise my code into several files. I have three files - a main python script and two other scripts stored in a subfolder. Excerpts provided below:

\myplugin.py:

from .mod import pmp as pmp
from .mod import helpers as h
class MyPlugin:
 def __init__(self, iface):
 self.iface = iface
 [...]
 h.msgInfo(self,"Plugin initialised!")
 pmp.test(self)

\mod\helpers.py:

import qgis.core as qgisCore
from qgis.core import Qgis, QgsApplication, QgsMessageLog
from qgis.gui import QgsMessageBar
def msgInfo(self, message, **kwargs):
 title = kwargs.get('t','')
 dur = kwargs.get('d',10)
 self.iface.messageBar().pushMessage(title, message, level=qgisCore.Qgis.Info, duration=dur)

\mod\pmp.py:

from . import helpers as h
def test(self):
 h.msgInfo(self,"PMP module successfully imported!")

Importing "helpers" is working perfectly for myplugin.py, as the "Plugin initialised!" message is showing as expected. Similarly, importing "pmp" seems to be working for myplugin.py. But when myplugin.py gets to this line:

pmp.test(self)

I get this error:

TypeError: test() takes 0 positional arguments but 1 was given

I've tried "self.pmp.test()" instead, but then of course I get "AttributeError: 'myplugin' object has no attribute 'pmp'".

If I use just "pmp.test()", then pmp.py gives me "NameError: name 'self' is not defined".

asked Jul 13, 2018 at 3:36
3
  • Why are you trying to pass self around? The self variable is a class idiom and is used by convention inside classes. You only seem to have functions defined and not classes...??? And why are you saving your python files with a .php file extension? Commented Jul 13, 2018 at 5:03
  • Oops - the .php extensions were typos - they're all .py files. I'll edit the question to fix that. I'm relatively new to python and must admit I don't really understand classes - would that be a better approach here? Commented Jul 13, 2018 at 5:09
  • P.S. myplugin.py is set up with a class structure (I'll also edit to include that code), as it was generated by a plugin builder plugin, but I haven't done that with the module files. Commented Jul 13, 2018 at 5:37

1 Answer 1

4

self is an internal variable that is a reference to the instance of your plugin class.

Don't pass self (itself :) to h.msgInfo, pass the iface object.

\myplugin.py:

from .mod import pmp as pmp
from .mod import helpers as h
class MyPlugin:
 def __init__(self, iface):
 [...]
 h.msgInfo(iface,"Plugin initialised!")
 pmp.test(iface)
 # Or 
 self.iface = iface #if you want to use iface anywhere else inside your MyPlugin class
 [...]
 h.msgInfo(self.iface,"Plugin initialised!")
 pmp.test(self.iface)

\mod\helpers.py:

import qgis.core as qgisCore
from qgis.core import Qgis, QgsApplication, QgsMessageLog
from qgis.gui import QgsMessageBar
[...]
def msgInfo(iface, message, **kwargs):
 title = kwargs.get('t','')
 dur = kwargs.get('d',10)
 iface.messageBar().pushMessage(title, message, level=qgisCore.Qgis.Info, duration=dur)

\mod\pmp.py:

from . import helpers as h
def test(iface):
 h.msgInfo(iface,"PMP module successfully imported!")
answered Jul 13, 2018 at 5:48
4
  • This doesn't appear to be working. To clarify, the problem is with pmp.py rather than helpers.py - the msgInfo() function in helpers.py was working perfectly, but no longer works if I make the changes you've suggested - I now get "AttributeError: 'QgisInterface' object has no attribute 'iface'." The test() function in pmp.py simply attempts to call the msgInfo() function from helpers.py (which is imported in pmp.py). The code in my original post includes both helpers.py and pmp.py in their entirety. Commented Jul 13, 2018 at 6:14
  • I've just updated the original post to include the line "self.iface = iface", which was also in the code originally but I had omitted it from my post. Commented Jul 13, 2018 at 6:19
  • OK, now I feel a little silly. I double-checked and it was definitely just "iface.messageBar()..." rather than "iface.iface.messageBar()..." Interestingly I still got the exact same error if I just used "messageBar()..." without the "iface" at the start... So instead of just reloading the plugin, I shut down QGIS and opened it again, and voila - all works perfectly. Thanks for your help! Commented Jul 13, 2018 at 6:36
  • Also, I've managed to prevent the error when reloading the plugin inside QGIS by adding "self.iface = None" immediately before "self.iface = iface". Commented Jul 13, 2018 at 6:49

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.