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?!
PyQt/PySide 1:1 Coaching with Martin Fitzpatrick — Save yourself time and frustration. Get one on one help with your Python GUI projects. Working together with you I'll identify issues and suggest fixes, from bugs and usability to architecture and maintainability.
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) !!!
Create GUI Applications with Python & Qt5 by Martin Fitzpatrick — (PyQt5 Edition) The hands-on guide to making apps with Python — Over 15,000 copies sold!
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_())