Anwendungsstart mittels 'Launcher'

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
Benutzeravatar
__LC__
User
Beiträge: 32
Registriert: Dienstag 1. März 2011, 14:08
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 30. August 2017, 09:46

Hallo liebe Community.

Ich bin gerade dabei eine kleine, auf dem Raspberry Pi laufende, Applikation zu überarbeiten. Grob gesprochen stellt diese Anwendung ein einfache Benutzerschnittstelle dar um mit Elektronik-Bausteinen via I2C zu kommunizieren. Grundsätzlich funktioniert das soweit auch, allerdings möchte ich den Anwendungsstart jetzt dahingehend modifizieren, dass bei diesem zunächst eine Überprüfung stattfindet ob alle Komponenten auch tatsächlich vorhanden sind. Der Fortschritt dieses Tests bzw. das Ergebnis dessen soll dann zunächst in einer Art 'Launcher' dem Anwender dargestellt werden, der bei Erfolg anschliessend die eigentliche Anwendung startet bzw. im Fehlerfall mittels einer einfachen Quittierung des Benutzers beendet werden soll. Soweit die prinzipielle Idee, allerdings fehlt es mir an einer konkreten Umsetzungsidee, weshalb ich mich sehr über ein paar Ideen/Ansätze von euch freuen würde. Im Voraus schon einmal herzlichen Dank!

Viele Grüsse
BlackJack

Mittwoch 30. August 2017, 09:56

@__LC__: Wo ist denn das konkrete Problem? Die Anwendung hast Du ja schon. Jetzt musst Du noch diesen Launcher schreiben und vor der Anwendung ausführen. Also statt

Code: Alles auswählen

starte_anwendung()
steht da dann

Code: Alles auswählen

if starte_launcher():
    starte_anwendung()
im Hauptprogramm.
Benutzeravatar
__LC__
User
Beiträge: 32
Registriert: Dienstag 1. März 2011, 14:08
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 30. August 2017, 11:18

Hallo BlackJack.

Ja, manchmal sieht man den Wald vor lauter Bäumen nicht mehr. Ich würde es jetzt prinzipiell so lösen:

Code: Alles auswählen

#!/usr/bin/python3
# -*- coding: utf-8 -*-

import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject

class TestApp:
    def __init__(self, *pargs, **kwargs):
        self.device_handler = None
    
    def setup(self):
        self.device_handler = DeviceHandler()
        launcher = Launcher(title='Launcher')
        launcher.set_position(Gtk.WindowPosition.CENTER) 
        launcher.show()
        if launcher.run() == 0:
            launcher.close()
            return 0
    
    def run_forever(self):
        user_interface = BaseGUI(title='Main user interface')
        user_interface.set_position(Gtk.WindowPosition.CENTER)
        # ToDo: connect user_interface and device_hander
        user_interface.run_forever()
    
    def shutdown(self):
        if self.device_handler is not None:
            self.device_handler.shutdown()

class Launcher(Gtk.Window):
    def __init__(self, *pargs, **kwargs):
        Gtk.Window.__init__(self, *pargs, **kwargs)
        self.set_default_size(500, 100)
        self.set_border_width(10)
    
    def run(self):
        self.connect('delete-event', Gtk.main_quit)
        Gtk.main()
        return 0

class BaseGUI(Gtk.Window):
    def __init__(self, *pargs, **kwargs):
        Gtk.Window.__init__(self, *pargs, **kwargs)
        self.set_default_size(450, 300)
        self.set_border_width(10)
        
    def run_forever(self):
        self.show()
        self.connect('delete-event', Gtk.main_quit)
        Gtk.main()

class DeviceHandler:
    def __init__(self):
        pass
    
    def shutdown(self):
        pass

if __name__ == '__main__':
    app = TestApp()
    if app.setup() is not None:
        app.run_forever()
        app.shutdown()
Eine Frage hätte ich aber dann noch. Zu Testzwecken würde ich gern in Launcher.run anstelle von

Code: Alles auswählen

self.connect('delete-event', Gtk.main_quit)
        Gtk.main()
eher einen Delay einbauen. Sprich das Launcher-Fenster sollte für 10 Sekunden angezeigt werden und sich dann schließen. time.sleep scheidet wohl aus.

Viele Grüße
Zuletzt geändert von __LC__ am Mittwoch 30. August 2017, 11:32, insgesamt 2-mal geändert.
__deets__
User
Beiträge: 2859
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mittwoch 30. August 2017, 11:29

Finde ich nicht so gut.

Das du den Launcher in die eigentlich App gefaltet hast macht es schwieriger, eine von beiden Komponenten unabhaenging voneinander zu entwickeln, testen und nutzen. Und erzeugt damit auch genau die Situation, welche dir die Probleme bereitet hat: zu viel Baueme.

Ruf den Launcher einfach gleich auf.

Und die setup-Methode hat eine Reihe von Problemen:

- man benutzt nicht 0 als Rueckgabewert um es dann gegen "None" als "alles ok"-Wert zu vergleichen. Zu dem zweck gibt es entweder Exceptions oder True/False. Dann wird der Test fuer die Rueckgabe auch ein einfaches

Code: Alles auswählen

if Launcher().run(): 
    ...
- desweiteren schliesst du den launcher nur, wenn er erfolgreich lief. Sollte das nicht immer passieren?
- du erzeugst einen DeviceHandler. Der hat eigentlich nichts mit dem Launcher zu tun. Wenn du das so auseinander ziehst wie vorgeschlagen, kannst du den auch einfach gleich in der App im Konstruktor erzeugen, statt da None zuzuweisen.
Antworten