win32ui.CreateFileDialog für Verzeichnisse

Fragen zu Tkinter.
Antworten
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Mit win32ui.CreateFileDialog kann man unter Windows einen Öffnen-Dialog zum Datei-Auswählen öffnen.

Gibt's sowas auch für Verzeichnisse? Notfalls auch mit TkInter, obwohl da einfach mehr Code notwendig ist.

P.S. Gibt's irgendwo eine ausführliche Doku, in der alle Klassen des Moduls "win32ui" erläutert werden?
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Der erste Link ist schonmal ganz hilfreich:

http://aspn.activestate.com/ASPN/docs/A ... n32ui.html

Allerdings finde ich dort kein Äquivalent für Verzeichnisse zu "CreateFileDialog". Ich könnte nur erahnen, dass vielleicht "CreateDialog" sowas sein könnte. Die Details dazu lauten:
win32ui hat geschrieben:win32ui.CreateDialog

PyCDialog = CreateDialog(idRes, dll )

Creates a dialog object.

Parameters

idRes : int

The ID of the dialog resource to load.

dll=None : PyDLL

The DLL object to load the dialog from.
Mir fehlt dazu ein Code-Beispiel oder sowas. Was ist z.B. die gewünschte "dialog resource" und wie erstelle ich die im Vorfeld?
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Es dürfte sich ja hierbei um die Umsetzung der Windowsfunktion CreateDialog handeln, die eine modeless-Dialogbox erzeugt.
Wie wäre es mit askdirectory in Tkinter. Sieh Dir mal die Datei tkFileDialog.py in Python24\Lib\lib-tk an!
MfG
HWK
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Jo, das war was! Ich hab grad angefangen Tkinter-Tutorials durchzugehen und hab schon meine ersten Fenster und den gewünschten Dir-Dialog mit Prüfung der Eingaben.

Wunderbar!
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Ich muss da nochmal was nachfragen, auch wenn's vielleicht besser ins Tkinter-Forum passt… Hier mein Programm in stark gekürzter Fassung:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: latin-1 -*-
import Tkinter as tk
import tkMessageBox, tkFileDialog, ScrolledText

class Gui:
	# constructor
	def __init__(self, master):
		# frame 1
		f1 = tk.Frame(master)
		f1.pack()
		# choose directory button
		optDirButton = tk.Button(f1, text="...", command=tkFileDialog.askdirectory)
		optDirButton.pack()
		# choose files button
		optFilesButton = tk.Button(f1, text="...", command=tkFileDialog.askopenfilenames(filetypes=[("Alle Dateien", "*.*"), ("Ausführbare Dateien", "*.exe *.dll *.com *.pif *.msi")]))
		optFilesButton.pack()

# direct file call
if __name__ == "__main__":
	root = tk.Tk()
	gui = Gui(root)
	root.mainloop()
Der Dialog für Dateien (tkFileDialog.askopenfilenames) öffnet sich sofort beim Programmaufruf. Dafür bewirkt ein Klick auf den zugehörigen Button Nichts. Würde ich die Klammern nach dem Funktionsaufruf weglassen, kommt der Dialog auch wirklich erst wenn ich auf den Button klicke. Würde dann also so aussehen:

Code: Alles auswählen

optFilesButton = tk.Button(f1, text="...", command=tkFileDialog.askopenfilenames)
Nur dass ich dann natürlich keine Tupel für Dateierweiterungen mehr mitgeben kann. Wie erklärt sich das und wie verhindere ich das?

Bei der Funktion 'tkFileDialog.askdirectory' verhält sich das genau so. Würde ich diese Funktion mit leeren Klammern aufrufen (so wie ich normalerweise auch meine Funktionen/Methoden aufrufen würde), käme der FileDialog ebenfalls sofort:

Code: Alles auswählen

optDirButton = tk.Button(f1, text="...", command=tkFileDialog.askdirectory())
jAN
User
Beiträge: 170
Registriert: Samstag 4. Juni 2005, 18:51
Wohnort: Großmehlra (in Thüringen)
Kontaktdaten:

so klappts:

Code: Alles auswählen

# -*- coding: latin-1 -*-
import Tkinter as tk
import tkMessageBox, tkFileDialog, ScrolledText

class Gui:
    # constructor
    def __init__(self, master):
        # frame 1
        f1 = tk.Frame(master)
        f1.pack()
        # choose directory button
        optDirButton = tk.Button(f1, text="...", command=tkFileDialog.askdirectory)
        optDirButton.pack()
        # choose files button
        optFilesButton = tk.Button(f1, text="...", command=self.foo)
        optFilesButton.pack()
    def foo(self):
        return tkFileDialog.askopenfilenames(filetypes=[("Alle Dateien", "*.*"), ("Ausführbare Dateien", "*.exe *.dll *.com *.pif *.msi")])

# direct file call
if __name__ == "__main__":
    root = tk.Tk()
    gui = Gui(root)
    root.mainloop()
#adios.py
import os,sys
while 1: os.startfile(sys.argv[0])
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Probier mal folgendes:

Code: Alles auswählen

#!/usr/bin/python 
# -*- coding: latin-1 -*- 
import Tkinter as tk 
import tkMessageBox, tkFileDialog, ScrolledText 

class Gui: 
    # constructor 
    def __init__(self, master): 
        # frame 1 
        f1 = tk.Frame(master) 
        f1.pack() 
        # choose directory button 
        optDirButton = tk.Button(f1, text="...",
                                 command=tkFileDialog.askdirectory) 
        optDirButton.pack() 
        # choose files button 
        optFilesButton = tk.Button(f1, text="...",
                command=lambda arg={'filetypes':[("Alle Dateien", "*.*"),
                ("Ausführbare Dateien", "*.exe *.dll *.com *.pif *.msi")]}:
                tkFileDialog.askopenfilenames(**arg)) 
        optFilesButton.pack() 

# direct file call 
if __name__ == "__main__": 
    root = tk.Tk() 
    gui = Gui(root) 
    root.mainloop() 
Du mußt eine Unterfunktion schreiben, um Parameter übergeben zu können, sonst wird die Funktion sofort ausgeführt. lambda ist praktisch eine Funktion ohne eigenen Namen.
MfG
HWK
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Nachtrag:
Da das Argument der lamda-Funktion konstant ist, geht es auch etwas einfacher:

Code: Alles auswählen

        optFilesButton = tk.Button(f1, text="...", 
                command=lambda: tkFileDialog.askopenfilenames(filetypes=
                        [("Alle Dateien", "*.*"), ("Ausführbare Dateien",
                        "*.exe *.dll *.com *.pif *.msi")])) 
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Danke das funzt soweit erstmal.

Aber warum muss man das tun? Oder anders: Weshalb werden Funktionsaufrufe mit leeren Klammern oder mit Parametern sofort ausgeführt?

Ich finde das komisch, wenn nicht sogar unlogisch...
BlackJack

Was ist daran komisch oder unlogisch? Ein Funktionsname ohne Klammern wird zum Funktionsobjekt ausgewertet und die Klammern bedeuten "Aufrufen mit folgenen Argumenten". Wenn die Klammern nicht den Aufruf "auslösen", wie sollte man das denn Deiner Meinung nach kennzeichen?

Beispiel: ``print "hallo".upper()`` würde nach Deiner Logik etwa sowas ausgeben: ``<built-in method upper of str object at 0xb7aa3c00>``

Das ist nicht das was die meisten Leute erwarten.
droptix
User
Beiträge: 521
Registriert: Donnerstag 13. Oktober 2005, 21:27

Klingt logisch. Ich hätte eben nur erwartet, dass das was hinter dem Istgleich steht erst passiert, wenn der "command" eintritt… Vergleichbar mit dem onlick-Ereignis bei HTML. Da steht auch z.B.

Code: Alles auswählen

<input type="button" onclick="myfunc('arg1', arg2)" />
Nun gut, das ist halt nur meine Erwartungshaltung :wink:
BlackJack

In dem Beispiel liegt das aber daran, das es kein JavaScript, sondern HTML ist. In JavaScript gelten für den Aufruf die gleichen Regeln wie bei Python, ohne Klammern hat man das Funktionsobjekt, mit Klammern den Aufruf. Und auch in JavaScrip kann man das Problem mit einer anonymen Funktion lösen.

Code: Alles auswählen

>>> add = function(a, b) { return a + b; }
function (a, b)
{
return a+b;
}
>>> typeof add
"function"
>>> typeof add(1, 2)
"number"
>>> typeof function () { return add(1, 2); }
"function"
>>> typeof function () { return add(1, 2); } ()
"number"
Antworten