0

I've tried to build a plugin from scratch to better understand the plugin structure and so on without the help of PluginBuilder or similar tools so my code could contain flaws. I went through every step by logic and I'm not sure about my structure.

Everything works fine until in the "run()" method of my main file(which Its name is ZVC.py) I try to import objects from my UI file(which Its name is ZVC_form.py).

In the "run()" method I want to import the ComboBoxes and fill them with open layers but it won't recognize my imported objects and it gives out "AttributeError: ZVC instance has no attribute 'comboBoxVector'" error.

Here is my structure:

main directory/
     ZVC.py   #main file
     ZVC_form.py   #pyuic4, generated python version of the UI file

Here is my Main file:(ZVC.py)(the problem lies in the last sentence of this file!)

from qgis.PyQt.QtGui import *
from qgis.PyQt.QtWidgets import *
import qgis
from ZVC_form import Ui_Form
import sys
import os

# initialize Qt resources from file resources.py
icon_path = os.path.join(os.path.dirname(__file__))+"/icon.png"

class ZVC:

  def __init__(self, iface):
    # save reference to the QGIS interface
    self.iface = iface
    self.Form = QWidget()
    Ui_Form().setupUi(self.Form)

  def initGui(self):
    # create action that will start plugin configuration
    self.action = QAction(QIcon(icon_path),  'Zonal Visibility Coverage'  , self.iface.mainWindow())
    self.action.setObjectName("Button")
    self.action.setWhatsThis("Configuration for test plugin")
    self.action.setStatusTip("This is status tip")
    self.action.triggered.connect(self.run)

    # add toolbar button and menu item
    self.iface.addToolBarIcon(self.action)
    self.iface.addPluginToMenu("&Zonal Visibility Coverage", self.action)

  def unload(self):
    # remove the plugin menu item and icon
    self.iface.removePluginMenu("&Zonal Visibility Coverage", self.action)
    self.iface.removeToolBarIcon(self.action)

  def run(self):

    # create and show a configuration dialog or something similar
    # show the dialog

    self.Form.show()
    Ui_Form.comboBox_vector.addItem("whatever") #this is the problem

and my UI file:(ZVC_form.py)

from PyQt4 import QtCore, QtGui
import core

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)


#This is the Class which let you to have a clickable QLineEdit
class LineEdit(QtGui.QLineEdit):
    def __init__(self, *args, **kwargs):
        super(LineEdit, self).__init__(*args, **kwargs)
        self.flag = False

    def mousePressEvent(self, event):
        if not self.flag:
            self.clear()
        self.flag = True
        self.setStyleSheet("color: rgb(0,0,0);")
        QtGui.QLineEdit.mousePressEvent(self, event)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(514, 300)
        Form.setMinimumSize(QtCore.QSize(514, 300))
        Form.setMaximumSize(QtCore.QSize(514, 300))

        self.lineEdit_refrac = LineEdit(Form)
        self.lineEdit_refrac.setGeometry(QtCore.QRect(140, 235, 361, 20))
        self.lineEdit_refrac.setObjectName(_fromUtf8("lineEdit_refrac"))
        self.lineEdit_refrac.setStyleSheet(_fromUtf8("color: rgb(120,120,120);"))
        self.lineEdit_refrac.setText("0.14285")

        self.label_refrac = QtGui.QLabel(Form)
        self.label_refrac.setGeometry(QtCore.QRect(10, 235, 111, 16))
        self.label_refrac.setObjectName(_fromUtf8("label_refrac"))

        self.label_input = QtGui.QLabel(Form)
        self.label_input.setGeometry(QtCore.QRect(10, 177, 81, 16))
        self.label_input.setObjectName(_fromUtf8("label_input"))

        self.label_vector = QtGui.QLabel(Form)
        self.label_vector.setObjectName(_fromUtf8("label_vector"))
        self.label_vector.setGeometry(QtCore.QRect(10, 207, 111, 16))

        self.comboBox_vector = QtGui.QComboBox(Form)
        self.comboBox_vector.setGeometry(QtCore.QRect(140, 205, 361, 20))
        self.comboBox_vector.setObjectName(_fromUtf8("comboBox_vector"))

        self.lineEdit_output = QtGui.QLineEdit(Form)
        self.lineEdit_output.setGeometry(QtCore.QRect(78, 261, 261, 20))
        self.lineEdit_output.setObjectName(_fromUtf8("lineEdit_output"))

        self.button_close_ok = QtGui.QDialogButtonBox(Form)
        self.button_close_ok.setGeometry(QtCore.QRect(341, 256, 161, 30))
        self.button_close_ok.setAutoFillBackground(False)
        self.button_close_ok.setStandardButtons(QtGui.QDialogButtonBox.Close | QtGui.QDialogButtonBox.Ok)
        self.button_close_ok.setCenterButtons(False)
        self.button_close_ok.setObjectName(_fromUtf8("button_close_ok"))

        self.comboBox_input = QtGui.QComboBox(Form)
        self.comboBox_input.setGeometry(QtCore.QRect(140, 175, 361, 20))
        self.comboBox_input.setObjectName(_fromUtf8("comboBox_input"))

        self.button_output = QtGui.QToolButton(Form)
        self.button_output.setGeometry(QtCore.QRect(8, 260, 61, 22))
        self.button_output.setObjectName(_fromUtf8("button_output"))

        self.farme_logo = QtGui.QFrame(Form)
        self.farme_logo.setGeometry(QtCore.QRect(0, 0, 511, 171))
        self.farme_logo.setStyleSheet("image: url(C:/Users/ash/.qgis2/python/plugins/ZVC/Logo.png);")
        self.farme_logo.setFrameShape(QtGui.QFrame.StyledPanel)
        self.farme_logo.setFrameShadow(QtGui.QFrame.Raised)
        self.farme_logo.setObjectName(_fromUtf8("farme_logo"))

        self.retranslateUi(Form)
        QtCore.QObject.connect(self.button_close_ok, QtCore.SIGNAL(_fromUtf8("accepted()")), lambda: self.intInput(Form)  )
        self.button_close_ok.rejected.connect(Form.close)  # This is the new form of connecting Singnals to Slots.
        self.button_output.clicked.connect(lambda: self.FileSave(Form))  # When you have set arguments such af "Form" in the function and want to call it with () at the end use lambda!
        QtCore.QMetaObject.connectSlotsByName(Form)
        Form.setTabOrder(self.comboBox_input, self.lineEdit_refrac)
        Form.setTabOrder(self.lineEdit_refrac, self.button_output)
        Form.setTabOrder(self.button_output, self.lineEdit_output)
        Form.setTabOrder(self.lineEdit_output, self.button_close_ok)

    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Zonal Visibility Coverage", None))
        self.lineEdit_refrac.setText(_translate("Form", "0.14286", None))
        self.label_input.setText(_translate("Form", "Input Raster", None))
        self.label_refrac.setText(_translate("Form", "Refraction Coefficient", None))
        self.button_output.setText(_translate("Form", "Output", None))
        self.label_vector.setText("Input Shape")

    def FileSave(self, Form):
        self.fileTypes = "TIFF format (*.tif);;Band interleaved by line (*.BIL);;Bitmap Image (*.BMP)"
        self.name = QtGui.QFileDialog.getSaveFileName(filter = self.fileTypes)
        self.lineEdit_output.setText(self.name)

    def intInput(self, Form):
        try:
            if self.lineEdit_output.text() == "":
                self.lineEdit_refrac.setText("Please choose an output direction")
            else:
                float(self.lineEdit_refrac.text())
                Form.lower()
                core.process()
        except ValueError:
            self.lineEdit_refrac.setText("Please fill only with numbers!")
0

Ah, I forgot to initialize UI_form! An easy thing to miss!

By doing self.UI = Ui_Form() at __init__ method of the main file and do the rest by using Self.UI the problem will be gone!

like self.UI.comboBox_vector.addItem("whatever") instead of Ui_Form.comboBox_vector.addItem("whatever").

The worst nightmares will happen if you are unable to debug your code in the IDE :(

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.