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".
1 Answer 1
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!")
-
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.Gareth Jones– Gareth Jones2018年07月13日 06:14:55 +00:00Commented 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.Gareth Jones– Gareth Jones2018年07月13日 06:19:22 +00:00Commented 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!Gareth Jones– Gareth Jones2018年07月13日 06:36:41 +00:00Commented 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".Gareth Jones– Gareth Jones2018年07月13日 06:49:37 +00:00Commented Jul 13, 2018 at 6:49
self
around? Theself
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?