yuriyrogalski11143 | 2021-05-11 11:45:54 UTC | #1
Hello dear Python Community,
its my first expecience to write a QGIS Plugin with PyQT5. With Plugin Builder i allready Set up the Development Folder and here i have those 3 Files (posted with the Code below) which i can open and execute with Atom and run in QGIS
SPBIM.py (as I understand the main File for writing my App) SPBIM_dialog.py (this File it tells me loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer SPBIM_dialog_base.py (File which was converted converted in cmd line with pyuic5 -x Plugin_dialog_base.ui -o Plugin_dialog_base.py - If i hadn't used the Qt Designer i could have Set up the Interface in here, but not sure the purpose of this File - if i have to add sth here
I have only a ComboBox and a Button Box Object: comboBox Class: QComboBox Object: button_box Class: QDialogButtonBox
The purpose of this Plugin (which is allready implemented in QGIS) is to Check the Values (5 Values set up in QtDesigner) the User activated/ picked in the Combobox !!!
Depending on the Value chosen - a bunch of more Python Code (5 different/ other Python Files) should be implemented/ executed/ run) - from File / in a Function?!
Create GUI Applications with Python & Qt5 by Martin Fitzpatrick — (PyQt5 Edition) The hands-on guide to making apps with Python — Over 10,000 copies sold!
i can activate self.comboBox in Plugin_dialog_base.py File (but not in SPBIM.py File)
Thank you for advise / hints help. Really trying to get this work done!
From other Forums i found the hint (but don't know how to implement this idea in the SPBIM_dialog.py File) Your "check boxes" don't work because you're putting your lines in the wrong place (run method). However, you need first to declare objects in init method for connecting them to a 'change_status' function (preferably one for each check box). I'm going to exemplify this only for "Interpretation" Check Box.
QGIS environment tells me in SPBIM.py it can't find my both Elemenets (combo_box, button_box) !!!
File: SPBIM.py
from qgis.PyQt.QtCore import QSettings, QTranslator, QCoreApplication
from qgis.PyQt.QtGui import QIcon
from qgis.PyQt.QtWidgets import QAction
# Initialize Qt resources from file resources.py
from .resources import *
# Import the code for the dialog
from .SPBIM_dialog import SPBIMDialog
import os.path
class SPBIM:
"""QGIS Plugin Implementation."""
def __init__(self, iface):
"""Constructor.
:param iface: An interface instance that will be passed to this class
which provides the hook by which you can manipulate the QGIS
application at run time.
:type iface: QgsInterface
"""
# Save reference to the QGIS interface
self.iface = iface
# initialize plugin directory
self.plugin_dir = os.path.dirname(__file__)
# initialize locale
locale = QSettings().value('locale/userLocale')[0:2]
locale_path = os.path.join(
self.plugin_dir,
'i18n',
'SPBIM_{}.qm'.format(locale))
if os.path.exists(locale_path):
self.translator = QTranslator()
self.translator.load(locale_path)
QCoreApplication.installTranslator(self.translator)
# Declare instance attributes
self.actions = []
self.menu = self.tr(u'&SPBIM')
# Check if plugin was started the first time in current QGIS session
# Must be set in initGui() to survive plugin reloads
self.first_start = None
# noinspection PyMethodMayBeStatic
def tr(self, message):
"""Get the translation for a string using Qt translation API.
We implement this ourselves since we do not inherit QObject.
:param message: String for translation.
:type message: str, QString
:returns: Translated version of message.
:rtype: QString
"""
# noinspection PyTypeChecker,PyArgumentList,PyCallByClass
return QCoreApplication.translate('SPBIM', message)
def add_action(
self,
icon_path,
text,
callback,
enabled_flag=True,
add_to_menu=True,
add_to_toolbar=True,
status_tip=None,
whats_this=None,
parent=None):
"""Add a toolbar icon to the toolbar.
:param icon_path: Path to the icon for this action. Can be a resource
path (e.g. ':/plugins/foo/bar.png') or a normal file system path.
:type icon_path: str
:param text: Text that should be shown in menu items for this action.
:type text: str
:param callback: Function to be called when the action is triggered.
:type callback: function
:param enabled_flag: A flag indicating if the action should be enabled
by default. Defaults to True.
:type enabled_flag: bool
:param add_to_menu: Flag indicating whether the action should also
be added to the menu. Defaults to True.
:type add_to_menu: bool
:param add_to_toolbar: Flag indicating whether the action should also
be added to the toolbar. Defaults to True.
:type add_to_toolbar: bool
:param status_tip: Optional text to show in a popup when mouse pointer
hovers over the action.
:type status_tip: str
:param parent: Parent widget for the new action. Defaults None.
:type parent: QWidget
:param whats_this: Optional text to show in the status bar when the
mouse pointer hovers over the action.
:returns: The action that was created. Note that the action is also
added to self.actions list.
:rtype: QAction
"""
icon = QIcon(icon_path)
action = QAction(icon, text, parent)
action.triggered.connect(callback)
action.setEnabled(enabled_flag)
if status_tip is not None:
action.setStatusTip(status_tip)
if whats_this is not None:
action.setWhatsThis(whats_this)
if add_to_toolbar:
# Adds plugin icon to Plugins toolbar
self.iface.addToolBarIcon(action)
if add_to_menu:
self.iface.addPluginToMenu(
self.menu,
action)
self.actions.append(action)
return action
def initGui(self):
"""Create the menu entries and toolbar icons inside the QGIS GUI."""
icon_path = ':/plugins/SPBIM/icon.png'
self.add_action(
icon_path,
text=self.tr(u'SPBIM'),
callback=self.run,
parent=self.iface.mainWindow())
# will be set False in run()
self.first_start = True
def unload(self):
"""Removes the plugin menu item and icon from QGIS GUI."""
print("UNLOADING Plugin")
for action in self.actions:
self.iface.removePluginMenu(
self.tr(u'&SPBIM'),
action)
self.iface.removeToolBarIcon(action)
def run(self):
"""Run method that performs all the real work"""
print("STARTING Plugin")
# Create the dialog with elements (after translation) and keep reference
# Only create GUI ONCE in callback, so that it will only load when the plugin is started
if self.first_start == True:
self.first_start = False
self.dlg = SPBIMDialog()
# show the dialog
self.dlg.show()
# Run the dialog event loop
result = self.dlg.exec_()
# See if OK was pressed
if result:
# Do something useful here - delete the line containing pass and
# substitute with your code.
#
#
pass
print("STARTING Plugin")
File: SPBIM_dialog.py
import os
from qgis.PyQt import uic
from qgis.PyQt import QtWidgets
# This loads your .ui file so that PyQt can populate your plugin with the elements from Qt Designer
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'SPBIM_dialog_base.ui'))
class SPBIMDialog(QtWidgets.QDialog, FORM_CLASS):
def __init__(self, parent=None):
"""Constructor."""
super().__init__(parent)
# Set up the user interface from Designer through FORM_CLASS.
# After self.setupUi() you can access any designer object by doing
# self.<objectname>, and you can use autoconnect slots - see
# http://qt-project.org/doc/qt-4.8/designer-using-a-ui-file.html
# #widgets-and-dialogs-with-auto-connect
self.setupUi(self)
File: SPBIM_dialog_base.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_SPBIMDialogBase(object):
def setupUi(self, SPBIMDialogBase):
SPBIMDialogBase.setObjectName("SPBIMDialogBase")
SPBIMDialogBase.resize(613, 184)
self.gridLayout = QtWidgets.QGridLayout(SPBIMDialogBase)
self.gridLayout.setObjectName("gridLayout")
spacerItem = QtWidgets.QSpacerItem(20, 72, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.gridLayout.addItem(spacerItem, 2, 0, 1, 1)
self.button_box = QtWidgets.QDialogButtonBox(SPBIMDialogBase)
self.button_box.setOrientation(QtCore.Qt.Horizontal)
self.button_box.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.button_box.setObjectName("button_box")
self.gridLayout.addWidget(self.button_box, 3, 3, 1, 1)
self.label = QtWidgets.QLabel(SPBIMDialogBase)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.comboBox = QtWidgets.QComboBox(SPBIMDialogBase)
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.gridLayout.addWidget(self.comboBox, 1, 0, 1, 1)
spacerItem1 = QtWidgets.QSpacerItem(225, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem1, 3, 2, 1, 1)
spacerItem2 = QtWidgets.QSpacerItem(228, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
self.gridLayout.addItem(spacerItem2, 1, 1, 1, 1)
self.retranslateUi(SPBIMDialogBase)
self.button_box.accepted.connect(SPBIMDialogBase.accept)
self.button_box.rejected.connect(SPBIMDialogBase.reject)
QtCore.QMetaObject.connectSlotsByName(SPBIMDialogBase)
def retranslateUi(self, SPBIMDialogBase):
_translate = QtCore.QCoreApplication.translate
SPBIMDialogBase.setWindowTitle(_translate("SPBIMDialogBase", "SPBIM"))
self.label.setText(_translate("SPBIMDialogBase", "XXX:"))
self.comboBox.setItemText(0, _translate("SPBIMDialogBase", "1. XXX"))
self.comboBox.setItemText(1, _translate("SPBIMDialogBase", "2. XXX"))
self.comboBox.setItemText(2, _translate("SPBIMDialogBase", "3. XXX"))
self.comboBox.setItemText(3, _translate("SPBIMDialogBase", "4. XXX"))
self.comboBox.setItemText(4, _translate("SPBIMDialogBase", "5. XXX"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
SPBIMDialogBase = QtWidgets.QDialog()
ui = Ui_SPBIMDialogBase()
ui.setupUi(SPBIMDialogBase)
SPBIMDialogBase.show()
sys.exit(app.exec_())