Gerätedialog in Python mit GTK darstellen

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Antworten
TimeMen
User
Beiträge: 55
Registriert: Samstag 24. Dezember 2016, 10:25
Wohnort: Deutschland

Da mir Glade nur Probleme bereitet hat baue ich das ganze nun einfach nur im Editor ohne Glade zu benutzen.
Vorab: Nutze Linux (Ubuntu Mate 16.04 o. Xubuntu 16.04)
Mein Problem:
Wie kann ich mit GTK sozusagen einen Gerätemanager bereitstellen, der sich z.B. auf Knopfdruck öffnet, wo ich dann alle Geräte (USB, CD, SD, HDD, SSD) angezeigt bekomme?
Es muss kein Button sein, es kann auch ein Menubutton oder sonst ein Auswahldialog sein.
Hauptsache ich kann dann das Gerät (in meinem Fall die SD Karte) auswählen.

LG
RouteUS66
Eine Signatur ist ein Text, der an deine Nachrichten angefügt werden kann. Sie ist auf 300 Zeichen begrenzt.
Benutzeravatar
BigZ
User
Beiträge: 30
Registriert: Mittwoch 1. Juli 2015, 21:18
Wohnort: Hamburg
Kontaktdaten:

http://stackoverflow.com/questions/2313 ... -in-python
Versteh deine Frage nicht so ganz, aber ist die zweite Antwort in dem Link das was du suchst?
Sprich so ein Auswahlfenster mit Verzeichnisbaum wo man eine Datei oder ein Verzeichnis auswählen kann?
Und ist doch kein Grund gleich die Schließung des Unterforums zu fordern, nur weil nicht gleich jemand ne Antwort parat hat.
Vielleicht einfach mal deutlicher erklären was man braucht.
Screenshot, Code, etc.
Ansonsten mal auf den Smiley klicken --> Bild
Hoffe das hilft weiter :mrgreen:
"Ist noch λ?"
"Ja, aber das ϕ ist noch ϱ"
TimeMen
User
Beiträge: 55
Registriert: Samstag 24. Dezember 2016, 10:25
Wohnort: Deutschland

Ich meinte ein MenuItem, dass mir alle verfügbaren USB Geräte, SDs und anderes anzeigt.
Hab das jetzt gelöst, allerdings kommt beim Auslesen der MenuItems immer nur None heraus.
Das ist nicht gerade hilfreich, wenn man ein Setup Programm für Raspbian Jessie Lite schreiben will.

LG
TimeMen
Eine Signatur ist ein Text, der an deine Nachrichten angefügt werden kann. Sie ist auf 300 Zeichen begrenzt.
BlackJack

@TimeMen: Ohne zu wissen wie und was Du genau machst, kann man nicht so gut sagen was das Problem ist. Mir war beim Ausgangsbeitrag auch noch nicht so ganz klar wo genau dort das Problem lag — am ermitteln der Geräte oder an der Anzeige.
TimeMen
User
Beiträge: 55
Registriert: Samstag 24. Dezember 2016, 10:25
Wohnort: Deutschland

@BlackJack
Ich wusste nicht wie ich das erklären sollte, und hatte gehofft, dass man es vielleicht auch so versteht.
http://i.imgur.com/UgWqcxf.png

So habe ich das jetzt gelöst, allerdings kann ich die MenuItems beim Klicken nicht auslösen, weil die automatisch generiert werden, und ich demnach nie weiß welches jetzt geklickt wurde...
Eine Signatur ist ein Text, der an deine Nachrichten angefügt werden kann. Sie ist auf 300 Zeichen begrenzt.
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@TimeMen: am Bild kann man nicht erkennen, was Du jetzt beim Anlegen der MenuItems falsch gemacht hast. Code sagt mehr als 1000 Bilder.
TimeMen
User
Beiträge: 55
Registriert: Samstag 24. Dezember 2016, 10:25
Wohnort: Deutschland

Hallo Sirius

Das Generieren der Einträge (Bin gerade auf der Suche nach einer besseren Methode ^^)

Code: Alles auswählen

self.menubar = Gtk.MenuBar()
        vbox.pack_start(self.menubar, True, True, 0)
        self.menu = Gtk.Menu()
        self.mb = Gtk.MenuButton(popup=self.menu)
        vbox.add(self.mb)
        basedir = '/dev/disk/by-path/'
        dev_list = {}
        counter = 0
        for d in os.listdir(basedir):
            #Only show usb disks and not partitions
            if 'usb' in d and 'part' not in d:
                path = os.path.join(basedir, d)
                link = os.readlink(path)
                dev_list[counter] = ('/dev/' + os.path.basename(link))
                counter += 1
        for i in range(counter):
            dev_list[i] = Gtk.MenuItem(label=dev_list[i])
            dev_list[i].connect("activate", self.on_device)
            dev_list[i].show()
            self.menu.append(dev_list[i])
Die Auswertung:

Code: Alles auswählen

def on_device(self, menu):
        device = self.mb.get_text()
        print(device)
        #device_lbl_str = "Device: <b>" + device + "<b>"
        #self.device_lbl.set_text(device_lbl_str)
Und da klappt eben die Auswertung nicht, da immer nur None rauskommt.
Eine Signatur ist ein Text, der an deine Nachrichten angefügt werden kann. Sie ist auf 300 Zeichen begrenzt.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du deine Datenstruktur schon "dev_list" nennst, sie aber dann zum Dictionary machst, dessen Schlüssel wiederum aufsteigende zahlen sind... dann ist das murks.

Nimm eine Liste, und gewöhn dir auch gleich ab mit Indizes auf die Daten zuzugreifen, sondern benutze iteration über die Liste um die Element zu bekommen.

Code: Alles auswählen

for device in devices:
    ...
Und was erwartest du soll denn passieren wenn du in deinem callback auf den einen Button zugreifst, der das popup öffnet? Der ist doch für alles devices gleich. Da musst du schon auf das Argument "menu" des callbacks zugreifen.
TimeMen
User
Beiträge: 55
Registriert: Samstag 24. Dezember 2016, 10:25
Wohnort: Deutschland

Natürlich ist das Murks,
aber ich habe es anders nicht hinbekommen.

Könntest du vielleicht ein Beispiel nennen, sodass ich das auch verstehe? ^^
Ich versuche mich mal selbst dran, aber wäre nett wenn du dir die Zeit dafür nehmen könntest

LG
Eine Signatur ist ein Text, der an deine Nachrichten angefügt werden kann. Sie ist auf 300 Zeichen begrenzt.
TimeMen
User
Beiträge: 55
Registriert: Samstag 24. Dezember 2016, 10:25
Wohnort: Deutschland

Okey, ich glaube ich habs jetzt:

Code: Alles auswählen

def init_dev_menu(self):
        for widget in self.devmenu.get_children():
            self.devmenu.remove(widget)

        basedir = '/dev/disk/by-path/'
        counter = 0
        dev_list = []
        for d in os.listdir(basedir):
            if 'usb' in d and 'part' not in d:
                path = os.path.join(basedir, d)
                link = os.readlink(path)
                dev_list.append('/dev/' + os.path.basename(link))
                counter += 1

        for device in dev_list:
            item = Gtk.MenuItem(device)
            self.devmenu.append(item)
            item.connect("activate", self.on_dev)
        self.devmenu.show_all(
Danke für den Tipp mit dem Iterieren, werde versuchen mich nun daran zu halten
Eine Signatur ist ein Text, der an deine Nachrichten angefügt werden kann. Sie ist auf 300 Zeichen begrenzt.
__deets__
User
Beiträge: 14493
Registriert: Mittwoch 14. Oktober 2015, 14:29

Jetzt darfst du noch die überflüssige Counter Variable loswerden, und den Menüeintrag gleich erzeugen statt in einer zweiten Schleife ;)
Sirius3
User
Beiträge: 17710
Registriert: Sonntag 21. Oktober 2012, 17:20

@__deeds__: besser wäre, das ganze in eine Funktion zu packen:

Code: Alles auswählen

import os
from glob import iglob

def iter_usb_devices():
    for device in iglob('/dev/disk/by-path/*usb*'):
        if 'part' not in os.path.basename(device):
            yield os.path.realpath(device)
BlackJack

Wobei das filtern nach *usb* problematisch ist, denn nicht alle Laufwerke/SD-Kartenleser sind per USB angeschlossen. Auf meinem Laptop würde der SD-Kartenleser von dem Programm beispielsweise nicht angezeigt werden.
Antworten