Pfad "." anzeigen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
PyGuest
User
Beiträge: 28
Registriert: Mittwoch 25. Mai 2022, 10:57

Hi,
die Frage klingt sicher seltsam, daher fällt die Antwort vielleicht völlig anders aus, als ich jetzt erwarten würde.

Ich versuche gerade, ein Python- Plugin für QGIS zu basteln und habe mich an diesem Tutorial entlanggehangelt:
https://docs.qgis.org/3.4/en/docs/pyqgi ... ugins.html

Vieles hat - nach ein paar Versuchen - dann auch wirklich funktioniert, aber final bin ich eben dann doch noch nicht durch.
Aus der Datei "ressouurces.qrc" habe ich an bezeichneter Stelle erfolgreich eine "ressources.py" gebastelt.

Und trotzdem kommt an genau dieser Stelle:

Code: Alles auswählen

from . import resources
die Fehlermeldung
"cannot import name 'resources' from 'QGisDummyPlugin' (C:/Users/MEIN_NAME/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\QGisDummyPlugin\__init__.py)"

Das System ist ein Windows- System, aber anscheinend dreht er die Slashes, wie er will. Abgesehen davon befindet sich die Datei ressources.py an genau der so bezeichneten Stelle.

Da ich nicht zu hoffen wage, dass sich hier jemand mit QGIS- Plugins auskennt, ist meine Frage ganz allgemein: Kann ich irgendwie ermitteln, welches Verzeichnis er als "." interpretiert?

Für Tips bin ich dankbar :)
Andreas
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@PyGuest: Da Du den Modulnamen alleine in diesem einen Beitrag in drei unterschiedlichen Varianten geschrieben hast, würde ich als erstes mal Buchstabe für Buchstabe den Dateinamen und den Importnamen vergleichen. 🙂
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Ernie1412
User
Beiträge: 160
Registriert: Freitag 10. Januar 2020, 20:38

C:/Users/MEIN_NAME/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\QGisDummyPlugin\__init__.py
denke mal / und dann \ im Pfad ist nicht gut :)
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Ernie1412: Es ist vielleicht nicht ästhetisch und man sollte das so auch nicht in den Quelltext schreiben, aber das hat ja auch niemand getan. Windows ist es egal ob / oder \ die Pfadkomponenten trennen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
PyGuest
User
Beiträge: 28
Registriert: Mittwoch 25. Mai 2022, 10:57

Hi,

ihr habt zwar meine Frage nicht beantwortet, aber dennoch mein Problem gelöst.
Tatsächlich war es ein Schreibfehler, da im Deutschen ressource mit Doppel- s geschrieben wird, im englischen aber nicht.

Kaum macht man's richtig, schon geht's :)

Allerdings würde ich mich dennoch freuen, wenn es zu meiner Frage eine Antwort gäbe. Gibt es eine solche?

Vielen Dank, egal, was noch kommt
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@PyGuest: Die Frage ist im Grunde schon beantwortet und zwar in Deinem eigenen Beitrag, denn dort steht ja der Pfad in der Ausnahme. Du hast nur nicht geglaubt, dass der auch stimmt. 😜

Ansonsten hat jedes Modul das eine Datei als Quelle hat den Namen `__file__` definiert. Also in dem Modul könntest Du einfach ``print(__file__)`` ausführen. Noch mehr Informationen gibt's mit `__spec__`. Das gibt es auch bei Modulen die nicht aus einer Datei kommen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
PyGuest
User
Beiträge: 28
Registriert: Mittwoch 25. Mai 2022, 10:57

Hast recht, hätte ich drauf kommen sollen. Allerdings habe ich immer noch ein (kleines?) Problem:

in QGIS kann man mit dem folgenden Befehl einem Icon ein "Bild" zuordnen:

Code: Alles auswählen

icon_file_name = r"resources\DummyIcon.png"
self.action = QAction(QIcon(icon_file_name), "Mein Dummy- Plugin", self.iface.mainWindow())
die Ordnerstruktur sieht so aus, dass ich im Unterordner "resources" eine Datei namens "DummyIcon.png" habe.
Allerdings wird das Icon nicht geladen, die Schaltfläche bleibt leer.

Wenn ich hingegen den absoluten Pfad angebe, dann funktioniert es.
Ein

Code: Alles auswählen

print (__file__)
ergibt
"C:/Users/ICH/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\QGisDummyPlugin3\mainPlugin.py"
wenn ich icon_file_name auf
"C:/Users/ICH/AppData/Roaming/QGIS/QGIS3\profiles\default/python/plugins\QGisDummyPlugin3\resources\DummyIcon.png"
setze, dann wird das Bild wie erwartet geladen.

Da das ganze letztlich in einer ZIP- Datei für ein Plugin landen soll, ist ein absoluter Pfad natürlich blöd. Und es erscheint mir auch nicht der vorgesehene Weg zu sein, mir aus __file__ und "resources\DummyIcon.png" etwas zusammenzubasteln.
Ich mache bestimmt wieder irgendetwas Banales falsch. Könnte mich jemand erleuchten?

Das funktioniert:

Code: Alles auswählen

icon_file_name = os.path.dirname(__file__)+r"\resources\DummyIcon.png"
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Doch. Das ist der Weg. Natuerlich nicht mit + und os.path, sondern pathlib. Aber sonst ist das schon der Weg.
PyGuest
User
Beiträge: 28
Registriert: Mittwoch 25. Mai 2022, 10:57

Na gut, dann eben so. Der "komplizierte" Umgang mit relativen Pfaden mutet ungewöhnlich an.
Vielen Dank für die Klarstellung
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Warum ist das für dich ungewöhnlich oder kompliziert?
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

PyGuest hat geschrieben: Freitag 1. Juli 2022, 11:24 Na gut, dann eben so. Der "komplizierte" Umgang mit relativen Pfaden mutet ungewöhnlich an.
Wenn der Pfad, in dem dein Skript liegt, der Ausgangspunkt ist, dann musst du den natürlich erst einmal ermitteln bevor du weitere relative Pfadbestandteile anhängst. So kompliziert ist das gar nicht.

Code: Alles auswählen

import pathlib

icon_file_name = patlib.Path(__file__).parent / "resources/DummyIcon.png"
PyGuest
User
Beiträge: 28
Registriert: Mittwoch 25. Mai 2022, 10:57

Bite versteht mich nicht falsch, natürlich kann man das so machen. Und vermutlich gibt es wenige Programmiersprachen, bei denen das so einfach ist.
Aber bei Softwareprojekten ist es doch grundsätzlich üblich, dass man diese strukturiert, also verschiedene Verzeichnisse anlegt für verschiedene Ressourcen (Icons, Bilder, Sounds ...) und die Software in kleinere Bestandteile zerlegt (Module, Pakete, Klassen ...).
Innerhalb eines Projektes ist es auch gängig, dass man auf diese Bestandteile und Ressourcen (kreuz und quer) zugreift. Deswegen kennen (eigentlich alle mir bekannten) Systeme einen Zugriff mittels relativen Pfaden etc. Aus meiner Sicht vereinfacht das die Wartbarkeit des Codes. Wenn ich neue Versionen oder Programmpakete basteln möchte, dann kann ich sie relativ leicht durch das ineinanderfügen von Ordnern realisieren.
Zur Laufzeit zu ermitteln, wo das Programmsystem sich manifestiert hat, damit man den dazu passenden absoluten Pfad "berechnen" kann, erscheint mir in diesem Zusammenhang eben ungewöhnlich.
Benutzeravatar
/me
User
Beiträge: 3554
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

PyGuest hat geschrieben: Montag 4. Juli 2022, 13:35 Deswegen kennen (eigentlich alle mir bekannten) Systeme einen Zugriff mittels relativen Pfaden etc.
Wenn du ausschließlich einen relativen Pfad verwendest, dann musst du halt sicherstellen, dass du vorher im passenden Verzeichnis bist.
Benutzeravatar
__blackjack__
User
Beiträge: 13003
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@PyGuest: Ich weiss nicht was Du sonst so programmierst, aber ich finde das ziemlich normal und erwartbar. Relative Pfadangaben sind nun mal relativ zum aktuellen Arbeitsverzeichnis, und das kann sonstwo sein. Wenn man etwas relativ zum Programmverzeichnis haben will, dann muss man das immer erst ”berechnen”. Oder mal legt Pfade beim übersetzen/installieren fest. In dem Fall kann man Programm/Daten danach nicht mehr verschieben.

Traditionell wird das in Python über das `__file__`-Attribut gemacht, was mit dem Dateisystem gut funktioniert. Ansonsten gibt es `importlib.resources()`, da muss man allerdings auf die Python-Version achten, welche da was unterstützt.

„Kreuz und quer” wäre in jedem Fall keine gute Idee. Überhaupt das Module Datendateien brauchen ist schon recht selten. Wenn dann gehören die ja eher zu Programmen. Und da ist dann auch wieder alles offen wo die Dateien hingehören. Unter Unix/Linux ja zum Beispiel nicht da wo das Program liegt und in Pfaden die einem bestimmten Muster folgen.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Qt zB liefert mit seinem QRC-Mechanismus sowas, aber C++ selbst kann das auch nicht besser, oder noch nicht mal so gut, wie Python. Und QRCs kann man auch in Python benutzen.
Antworten