Skip to content

Python3 - Global variable 'widget' undefined at the module level

Python3
  • Jeder Python3 Einsteiger dürfte diese Meldung kennen. Auch in meinem Projekt nutze ich einige wenige Variablen an verschiedenen Stellen im Code. Das wirft dann in Pylint diese Fehlermeldung. Im verlinkten Beitrag findet man eine Erklärung warum das so ist.

    global tells python to look for a variable with this name in the global namespace and include it in the local namespace. This means it must exist in the global namespace first.

    import sys
    from PyQt5.QtWidgets import QApplication, QWidget
    
    m = None  # variable must exist in global namespace first
    
    def show():
        global m  # this creates a local m that is linked to the global m
        m = QWidget()
        m.setWindowTitle("Testing this app")
        m.show()
    
    MYAPP = QApplication(sys.argv)
    show()
    MYAPP.exec_()
    

    Das Beispiel aus dem Beitrag, zeigt das man die Variable im globalen Raum vorher deklarieren muss. Das mache ich jetzt so

    ###############################################
    ## Set global variables to avoid this message
    ## Global variable 'widget' undefined at the module level
    ###############################################
     
    widget = None
    mount_path = None
    restore_path = None
    row = None
    load_data = None
    

    Es wird überall immer erwähnt, das man globale Variablen unbedingt vermeiden soll. Das soll kein guter Programmierstil sein!? Dann habe ich jetzt eine gute Liste, um welche Variablen ich mich kümmern muss und werde diesen Teil so umschreiben, das ich das vermeiden kann.

    Quelle: https://stackoverflow.com/questions/55765372/python-error-global-declared-variable-is-not-declared-in-the-global-scope

  • Ok, da ich gestern schon wieder gelesen habe, das globale Variablen unbedingt zu vermeiden sind, habe ich mich mal dran gesetzt und nochmal drüber nachgedacht. Ausgangslage

    b9604f15-6e82-4865-bc44-f9ab2db2614e-grafik.png

    Die Einträge in der Backup List kann man per Mausklick auswählen und die Nummer des gewählten Eintrages brauch ich überall im Projekt.

    • kann man mit global row machen
    • kann man mit settings.setValue(entry_name, entry_value) machen
    • kann man mit einer Klasse lösen

    Mein erster Ansatz war, das mit global row zu machen. Das funktioniert auch einwandfrei. Mein zweiter Ansatz war, den Eintrag in einer Datei settings zu speichern. Auch das funktionierte einwandfrei. Aber beim Nachdenken, fiel mir dann wieder ein, ich muss mehr mit Klassen machen 😉

    Und genau beim Schreiben dieser Klasse ist mir dann aufgefallen, das das überhaupt nicht nötig ist 🤓

    Man kann sich doch die Zeile direkt holen.

    row = self.listWidget.currentRow()
    

    Die Zeile in allen Funktionen hinzugefügt und die globale Variable row war Geschichte. Jepp, man lernt Stück für Stück dazu...

  • Kein globalen Variablen mehr im Projekt 🙂

    Das Widget ließ sich relativ einfach erledigen.

    Vorher

    #----QPlainTextEdit ----#
    layout = QVBoxLayout()
    widget = QTextEdit()
    widget.setReadOnly(True)
    widget.setLayout(layout)
    setCentralWidget(widget)
    

    Nachher

    #----QPlainTextEdit ----#
    layout = QVBoxLayout()
    self.widget = QTextEdit()
    self.widget.setReadOnly(True)
    self.widget.setLayout(layout)
    self.setCentralWidget(self.widget)
    

    Aufruf dann nicht mehr mit

    # UI
    widget.setHtml("")
    

    sondern mit

    # UI
    mainWin.widget.setHtml("")
    

    Problem erledeigt und hoffentlich auch verstanden 😉

  • Python - Formatumwandlung str -> float

    Python3
    1
    0 Stimmen
    1 Beiträge
    160 Aufrufe
    Niemand hat geantwortet
  • Python - Frameworks

    Python3
    2
    0 Stimmen
    2 Beiträge
    76 Aufrufe
    FrankMF

    Und mal hier parken

  • Python - Match-Case Statement

    Python3
    1
    0 Stimmen
    1 Beiträge
    83 Aufrufe
    Niemand hat geantwortet
  • PyQt5 - QThread

    Python3
    3
    0 Stimmen
    3 Beiträge
    140 Aufrufe
    FrankMF

    Und hier mal ein komplettes Beispiel.

    class Worker

    Wir legen den Worker an, das ist der Prozess der die Arbeit macht und etwas länger braucht.

    class Worker(QObject): """ Worker Class for Rest function stats""" stats_finished = pyqtSignal(str) stats_error = pyqtSignal(str) def __init__(self): super().__init__() def run(self): # Restic function try: # long running task except Exception: # Process don't successful, send signal self.stats_error.emit(result.stderr) else: # Process successful, send signal self.stats_finished.emit(result.stdout) finally: pass in class MainWindow class MainWindow(QMainWindow): def __init__(self): super().__init__() "First Thread with documentation" # Worker for restic_stats # Create a QThread object self.thread = QThread() # Create a worker object self.worker1 = Worker() # Move worker to the thread self.worker1.moveToThread(self.thread) # Connect signals and slots self.thread.started.connect(self.worker1.run) self.worker1.stats_finished[str].connect(self.restic_stats_finished) self.worker1.stats_error[str].connect(self.restic_stats_error) "First thread end" ############################################### # Process for restic_stats is finished ############################################### @pyqtSlot(str) def restic_stats_finished(self, i): # Signal from worker thread without an error Spinner.stop(self) self.thread.quit() ############################################### # Process for restic_stats when get an error ############################################### @pyqtSlot(str) def restic_stats_error(self, i): # Signal from worker thread with an error! Spinner.stop(self) Funktion restic_stats def restic_stats(self): # we start the worker thread self.thread.start() # we start waitingspinnerwidget Spinner.start(self)

    Ich wollte gerade schreiben, das folgendes sehr wichtig ist

    self.thread.quit()

    da fällt mir ein Fehler auf. Kurz ausprobiert und bingo, wenn der Prozess einen Error triggert, muss natürlich auch der Prozess beendet werden. Wenn man das nicht macht, macht das Programm nicht das was es soll. Der Grund ist, das der Prozess einfach immer weiter läuft. Er MUSS beendet werden. Ich gehe dann mal in meinem Programm alles ändern 🙂

    Ok, jetzt geht die Funktion auch zweimal hintereinander und gibt auch ordentlich den Fehler aus.

    Fazit

    Ich habe wieder sehr viel gelernt und hoffe das ich es auch richtig verstanden habe 😉 Hoffe das es dem ein oder anderen Anfänger hilft. Und falls hier ein Profi mitliest und hier Blödsinn steht bitte ich um einen Kommentar, damit ich das ändern kann. Es steht schon genug Blödsinn im Netz 🙂

  • Restic UI - Changelog

    Angeheftet Restic UI
    3
    0 Stimmen
    3 Beiträge
    262 Aufrufe
    FrankMF

    v1.5.0 - Release for restic v0.14.0 with compression and migration tool

  • 0 Stimmen
    1 Beiträge
    168 Aufrufe
    Niemand hat geantwortet
  • Python3 - virtuelle Entwicklungsumgebung

    Angeheftet Python3
    3
    0 Stimmen
    3 Beiträge
    301 Aufrufe
    FrankMF

    Nach Systemwechsel erneut Probleme. Hier noch mal aufgelistet.

    Aufpassen, das kein venv Ordner vorhanden ist! Neu anlegen!

    python3 -m venv venv

    Dann meckert mein Linux Mint Cinnamon

    The virtual environment was not created successfully because ensurepip is not available. On Debian/Ubuntu systems, you need to install the python3-venv package using the following command. apt install python3.8-venv You may need to use sudo with that command. After installing the python3-venv package, recreate your virtual environment. Failing command: ['/home/frank/Restic_UI_Produktiv/restic-ui-public/venv/bin/python3', '-Im', 'ensurepip', '--upgrade', '--default-pip']

    Ok, das ist einfach 😉

    apt install python3.8-venv python3 -m venv venv

    Danach aktivieren

    source venv/bin/activate Installation von PyQt5 (venv) frank@frank-MS-7C37:~/Restic_UI_Produktiv/restic-ui-public$ pip3 install PyQt5 Collecting PyQt5 Downloading PyQt5-5.15.4-cp36.cp37.cp38.cp39-abi3-manylinux2014_x86_64.whl (8.3 MB) |████████████████████████████████| 8.3 MB 1.7 MB/s Collecting PyQt5-Qt5>=5.15 Downloading PyQt5_Qt5-5.15.2-py3-none-manylinux2014_x86_64.whl (59.9 MB) |████████████████████████████████| 59.9 MB 18.3 MB/s Collecting PyQt5-sip<13,>=12.8 Downloading PyQt5_sip-12.9.0-cp38-cp38-manylinux1_x86_64.whl (332 kB) |████████████████████████████████| 332 kB 46.1 MB/s Installing collected packages: PyQt5-Qt5, PyQt5-sip, PyQt5 Successfully installed PyQt5-5.15.4 PyQt5-Qt5-5.15.2 PyQt5-sip-12.9.0

    Danach meckert er über ein fehlendes Modul requests

    (venv) frank@frank-MS-7C37:~/Restic_UI_Produktiv/restic-ui-public$ python3 restic_ui.py Traceback (most recent call last): File "restic_ui.py", line 41, in <module> from functions import ( File "/home/frank/Restic_UI_Produktiv/restic-ui-public/functions.py", line 19, in <module> import requests as req ModuleNotFoundError: No module named 'requests' Installation requests (venv) frank@frank-MS-7C37:~/Restic_UI_Produktiv/restic-ui-public$ pip3 install requests Collecting requests Downloading requests-2.25.1-py2.py3-none-any.whl (61 kB) |████████████████████████████████| 61 kB 802 kB/s Collecting chardet<5,>=3.0.2 Downloading chardet-4.0.0-py2.py3-none-any.whl (178 kB) |████████████████████████████████| 178 kB 2.7 MB/s Collecting certifi>=2017.4.17 Downloading certifi-2021.5.30-py2.py3-none-any.whl (145 kB) |████████████████████████████████| 145 kB 14.0 MB/s Collecting idna<3,>=2.5 Downloading idna-2.10-py2.py3-none-any.whl (58 kB) |████████████████████████████████| 58 kB 9.4 MB/s Collecting urllib3<1.27,>=1.21.1 Downloading urllib3-1.26.6-py2.py3-none-any.whl (138 kB) |████████████████████████████████| 138 kB 11.5 MB/s Installing collected packages: chardet, certifi, idna, urllib3, requests Successfully installed certifi-2021.5.30 chardet-4.0.0 idna-2.10 requests-2.25.1 urllib3-1.26.6

    Und schwupps, geht mein Tool wieder 🙂

    4968ce42-7c66-4c8a-a2ad-424b9a529d87-grafik.png

  • Wichtige Links

    Angeheftet Python3
    1
    0 Stimmen
    1 Beiträge
    170 Aufrufe
    Niemand hat geantwortet