Erstellung eines Windows-Shell-Befehls mit askopenfilename

Fragen zu Tkinter.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Ich kann dir auch nochmal ein OOP script geben, allerdings halte ich das hier für unötig, da du die Form weder irgendwo einbinden noch sonst wie nutzen willst, sondern nur in deinem "Hauptscript".

Das "all((filename, filename_a))", wird erfüllt, wenn die String darin nicht leer sind, hier habe ich aber die "_" Unterstriche vor beiden vergessen, also sind sie immer leer. Werde da oben gleich mal korrigieren.
Ich möchte auch nochmal betonen, das Dauerbaustelle recht hat, die **-Magie, sollte nie oder halt nur bedingt, wenn man keine andere Wahl hat genutzt werden.

Zu deiner Form die du haben willst könntest du da mal eine knappe Skizze machen, oder dies etwas detailierter Beschreiben ?
Aber Prinzipiell, sollte es nicht allzu schwer sein. Wenn du aber hier mehrere von den hier erwähnten Widgets brauchst bietet sich OOP wieder an.

Das Sortieren, musst du in der Logik machen die GUI sollte nur der Anzeige der Daten dienen, hier sollte nichts sortiert werden.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Dauerbaustelle
User
Beiträge: 996
Registriert: Mittwoch 9. Januar 2008, 13:48

Xynon1 hat geschrieben:
Dauerbaustelle hat geschrieben:Also ich persönlich finde es übersichtlicher, Keyword-Argumente auf mehrere Zeilen innerhalb der "Aufruf-Klammer" zu verteilen anstatt erst mal das Dictionary zu erstellen und dann mit **-Magie zu übergeben..
Wie ich schon gesagt habe war es hier nicht wirklich Notwendig und man hätte es sicher auch so wie du vorgeschlagen hast machen können, wenn du aber größere Optionale Parameter hast bekommt man mit deiner Methode auch Schwierigkeiten. Zudem sollte man solche Funktionen/Methoden überhaupt nicht schreiben, die sowas zulassen, denn dafür brauchst du auch die **-Magie. Wenn du das also in deinen Beispielen so umsetzt könnte ich jetzt auch behaupten das du Anfängern nicht idiomatische (unidiomatiosches :) ) Python beibringst, da dies auch nicht die Regel sein sollte. (Tkinter ist echt verkorkst :D )
Ich komm nicht mit. Wann bekommt man denn damit Schwierigkeiten, wenn man Keyword-Argumente in der vorgesehenen Weise, nämlich in den "Aufruf-Klammern", übergibt?
Dauerbaustelle hat geschrieben:Ich wollte eigentlich darauf raus, dass man üblicherweise statt
Ich hatte eigentlich in Erinnerung das das egal wäre, zugegeben dict() ist etwas langsamer und akzeptiert auch nur 255 Argumente und nimmt auch keine Zahlen als Key, aber solange man nicht eine diese Parameter überschreitet ist es eigentlich egal.
Deswegen spreche ich ja auch von "üblicherweise" und "idiomatischem" Python. Der üblicherweise verwendete -- und damit ein Standard, auch wenn nicht formal erzwungen -- Weg ist eben die Literalform.
Zu guter letzt ein paar Beispiele, was ich hier meine:
Toplevel, Button, Canvas, Frame, Text, ... Konstrucktor:

Code: Alles auswählen

def __init__(self, master=None, cnf={}, **kw):
Fast alle lassen die Wahl ob man cnf die Referenz eines Wörterbuches übergeben möchte, oder ob man sie als Argument Parameter übergibt.
Man hat eigentlich *immer* die Wahl, es sei denn, es gibt ein ``*args`` hinter Argumenten mit Default-Wert, etwa so:

Code: Alles auswählen

def foo(x, y=z, *args)
Dann kann man zusätzliche positionale Argumente nur dann angebene, wenn man ``y`` nicht als Keyword-Argument angibt. Meintest du das? Das hat dann auch nichts mit der Funktionssignatur zu tun, sondern das ist einfach eine Einschränkung von CPython.
colonelkurtz
User
Beiträge: 6
Registriert: Freitag 21. Januar 2011, 15:42

Hallo zusammen,

im folgenden die Skizze, so wie ich mir die GUI des Skripts vorstelle. Das Skript existiert schon fast vollständig ohne GUI. Es besteht nur aus ein paar Schleifen und Funktionsaufrufen. Ich hoffe die große Auflösung der Skizze stört nicht.

Bild

MfG,

Kurtz
Zuletzt geändert von colonelkurtz am Mittwoch 26. Januar 2011, 13:28, insgesamt 1-mal geändert.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Dauerbaustelle hat geschrieben:Ich komm nicht mit. Wann bekommt man denn damit Schwierigkeiten, wenn man Keyword-Argumente in der vorgesehenen Weise, nämlich in den "Aufruf-Klammern", übergibt?
Nur bei der Übersichtlichkeit, wie ich schon mehrfach geschrieben hatte. Ansonst ist nur das Problem, das man keinen Zugriff mehr auf die übergebene Dictionary hat. Was aber in Tkinter mit ".configure"/".config" umgangen wurde und somit auf indirekte Art wieder möglich ist.
Dauerbaustelle hat geschrieben:Deswegen spreche ich ja auch von "üblicherweise" und "idiomatischem" Python. Der üblicherweise verwendete -- und damit ein Standard, auch wenn nicht formal erzwungen -- Weg ist eben die Literalform.
Ok, sehe ich ein, ich hatte dict nur immer gerne bei Einzeilern verwendet, lässt sich aber ändern.
Dauerbaustelle hat geschrieben:Man hat eigentlich *immer* die Wahl, es sei denn, es gibt ein ``*args`` hinter Argumenten mit Default-Wert, ...
Mir gehts hier nicht um Positionale Parameter im Allgemeinen, sondern um nur den "cnf", oder "options"-Parameter in den Tkinter-Klassen und Funktionen, denn dieser erwartet ein Wörterbuch, welches man auch als Schlüssel Argumente an "**kw" übergeben kann.
Über die "Tkinter._cnfmerge"-Funktion, werden diese immer zusammen gepackt und die Optionen ausgelesen und verwertet. Und die Wahl hat man halt nicht immer, denn diese muss von der API vorgegeben sein, weil die Optionen daraus ausgelesen werden müssen.
*args könnte dann ja hinter der Konfigvariable(cnf) kommen, was ja dennoch möglich wäre.
Dauerbaustelle hat geschrieben:Dann kann man zusätzliche positionale Argumente nur dann angebene, wenn man ``y`` nicht als Keyword-Argument angibt. Meintest du das? Das hat dann auch nichts mit der Funktionssignatur zu tun, sondern das ist einfach eine Einschränkung von CPython.
Das hat damit halt nicht viel zu tun, denn es geht hier weder um CPython, noch um eine unbegrenzte Zahl positionaler Argumente, sondern lediglich um die interne Strucktur von Tkinter.

@colonelkurtz
Man hätte die Skizze auch kurz runter skalieren können und unten den freien wegschneiden können.
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
colonelkurtz
User
Beiträge: 6
Registriert: Freitag 21. Januar 2011, 15:42

Servus,

nur kurz zur Info: Das Bild der Skizze wurde etwas handlicher skaliert.

MfG,

Kurtz
Zuletzt geändert von colonelkurtz am Mittwoch 26. Januar 2011, 13:57, insgesamt 2-mal geändert.
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

Die GUI sollte jetzt eigentlich kein großes Problem darstellen, versuch dich erstmal selbst daran und wenn es Schwierigkeiten gibt melde dich nochmal.

Für "gelabelte" Eingabefelder habe ich hier noch was, falls du Interesse hast: http://www.python-forum.de/pastebin.php?mode=view&s=136
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
colonelkurtz
User
Beiträge: 6
Registriert: Freitag 21. Januar 2011, 15:42

So, ich muss nochmal nerven:

@Xynon1: Das Skript tut's nicht. Leider weiß ich nicht, wass 'if all(...' in der say-hi-Funktion prüfen will. Jedoch scheint diese Prüfung nicht erfüllt zu sein. Eine 'print 'test'' Ausgabeaufforderung in der Konsole wird nicht nachgegangen, sobald der 'Starte Rechnung'-Button geklickt wird.

Falls Du demnächst noch einmal Zeit hast, würde ich Dich bitten, die angesprochene if-Bedingung mit einem print 'x-beliebiger String' zu testen und erstmal den subprocess.Popen-Befehl außen vor zu lassen.

Dann mache ich selbst mit der Widget-Erzeugung weiter und will aufhören zu fragen ;).
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hallo colonelkurtz

Diese Ergänzung macht das Skript von Xynon1 lauffähig:

Code: Alles auswählen

app_win = tkinter.Tk()
app_win.title('Labeld_Frame')

label_entry = LabelEntry(app_win, 'Hallo')
label_entry.pack()

app_win.mainloop()
Gruß wuf :wink:
Take it easy Mates!
Xynon1
User
Beiträge: 1267
Registriert: Mittwoch 15. September 2010, 14:22

oder besser doch her mit den Objekten. - Ist mir sowieso lieber.

So hier als Objekt und ohne die von Dauerstelle bemängelten **-Magie, also idiomatisches Python, sollte das irgendwo nicht der Fall sein, gebt mir Bescheid:

Code: Alles auswählen

#!/usr/bin/env python
import os
import subprocess
import Tkinter as tkinter
import tkFileDialog

PACK_STYLE = {"expand":True, "fill":"both", "padx":1, "pady":1}

class FileOpener(tkinter.Frame):

    def __init__(self, master, cnf=()):
        tkinter.Frame.__init__(self, master, cnf)
        self.filename = ""
        self.dialog = tkFileDialog.Open(self)

    def create(self, text="select", dialog_options=()):
        button_options = {"text" : text.title(),
                          "command" : lambda: self.filedialog(dialog_options)}
        self.button = tkinter.Button(self, button_options)
        self.button.pack(PACK_STYLE)

    def filedialog(self, options=()):
        self.dialog.options = options
        self.filename = self.dialog.show()
        

def print_(exe_name, dat_name):
    print(exe_name, dat_name)
   
if __name__ == "__main__":
    path_to_exe = "D:\\User\\bin\Programme\\TXpert"
    path_to_dat = "D:\\Scripting-Unterlagen\\Python\\Skripte\\Beispiel_" \
                  "Drosselpunkt\\T5422_Buchmann_Rinnthal\\Test-Rechnungen"
   
    root = tkinter.Tk()
    root.title("tw0070")
    
    exe = FileOpener(root)
    exe_title = "W\xe4hle tw0070-Version"
    exe_options = {"initialdir" : path_to_exe,
                   "filetypes" : [("executable files", ".exe"),
                                  ("all files", ".*")],
                   "title" : exe_title}
    exe.create(exe_title, exe_options)
    exe.pack(PACK_STYLE)
    
    dat = FileOpener(root)
    dat_title = "W\xe4hle tw0070-Eingabedatei"
    dat_options = {"initialdir" : path_to_dat,
                   "filetypes" : [('data', '.dat'), ('all files', '.*')],
                   "title" : dat_title}
    dat.create(dat_title, dat_options)
    dat.pack(PACK_STYLE)

    start_options = {"text" : "Starte Rechnung",
                     "command" : lambda: print_(exe.filename, dat.filename)}
    start = tkinter.Button(root, start_options)
    start.pack(PACK_STYLE)

    root.mainloop()
Traue keinem Computer, den du nicht aus dem Fenster werfen kannst.
Xynon auf GitHub
Antworten