Inspiration for this answer was found in @J.Monticolo's comment > sorry @taras, I missread. So, for me, put the `startup.py` file into a > `your_plugin_name_or_whatever.py`, do a function called `def > launch_code` and put the `startup.py` "code that runs the program" > part into it, and then, in you plugin generated by `pb_tool`, put a > call to `launch_code` in the `def run`, function called by plugin menu > button click. and in this article : [Customizing QGIS with Python | 14.1 A Minimal Plugin](https://courses.spatialthoughts.com/pyqgis-in-a-day.html#a-minimal-plugin). ### This steps helped me to achieve the aim **Step 1.** Put the content of the `startup.py` file inside of one function e.g. `launch_code()` in a new Python file ## `main.py` : def launch_code(): imports import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5.QtGui import * from qgis.core import * from qgis.utils import * from qgspasswordlineedit import QgsPasswordLineEdit ---------------------------- configuration files ---------------------------- functions ---------------------------- layouts / pages ###Layouts #Page1 class IntroPage(QWizardPage): def __init__(self, parent=None): super(IntroPage, self).__init__(parent) ... #Page2 class LayerPage(QWizardPage): def __init__(self, parent=None): super(LayerPage, self).__init__(parent) ... #page 3 class AuthPage(QWizardPage): def __init__(self, parent=None): super(AuthPage, self).__init__(parent) ... #QWizard Class class Window(QWizard): def __init__(self): super(Window, self).__init__() #adds Pages to Wizard self.IntroPage = IntroPage() self.LayerPage = LayerPage() self.AuthPage = AuthPage() self.addPage(self.IntroPage) self.addPage(self.LayerPage) self.addPage(self.AuthPage) #Button check if Oracle or Postgre Data selected self.button(QWizard.NextButton).clicked.connect(lambda x:OraclePostgreCheck(self.AuthPage.frame_2, self.AuthPage.frame_4)) #Readjust GUI size at buttonclick self.button(QWizard.NextButton).clicked.connect(self.adjustSize) self.button(QWizard.BackButton).clicked.connect(self.adjustSize) ---------------------------- code that runs the program ### #Programm starts #loadConfigCSV(URI,";") loadPaketConfigJSON(PURI) loadConfigJSON(URI) kategoriesJSON() #loadConfigtoQGIS() #load config for export during development #GUI window = Window() window.setWizardStyle(1) window.show() #Programm ends ### **Step 2.** Create two Python files `qgsdata.py` and `__init__.py` that will bring this Plugin into action ## `qgsdata.py` : <!-- language: python --> import os import inspect from PyQt5.QtGui import * from PyQt5.QtWidgets import * from qgis.core import * from qgis.utils import * from .main import launch_code cmd_folder = os.path.split(inspect.getfile(inspect.currentframe()))[0] class QgsDataPlugin: def __init__(self, iface): self.iface = iface def initGui(self): icon = os.path.join(os.path.join(cmd_folder, 'icon.png')) self.action = QAction(QIcon(icon), 'QgsData', self.iface.mainWindow()) self.action.triggered.connect(self.run) self.iface.addPluginToMenu('&My Plugins', self.action) self.iface.addToolBarIcon(self.action) def unload(self): self.iface.removeToolBarIcon(self.action) self.iface.removePluginMenu('&My Plugins', self.action) del self.action def run(self): launch_code() ## `__init__.py` : <!-- language: python --> # noinspection PyPep8Naming def classFactory(iface): # pylint: disable=invalid-name """ Load QgsData class from file QgsData. :param iface: A QGIS interface instance. :type iface: QgsInterface """ from .qgsdata import QgsDataPlugin return DataPlugin(iface) **Step 3.** Create corresponding `metadata.txt` and `pb_tool.cfg` **Step 4.** Run the `pbt deploy` command in the CMD and get a working QGIS Plugin under `C:\Users\taras\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\QgsDataPlugin`