Seite 1 von 1

win32ui.CreateFileDialog für Verzeichnisse

Verfasst: Freitag 18. August 2006, 10:19
von droptix
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?

Re: win32ui.CreateFileDialog für Verzeichnisse

Verfasst: Freitag 18. August 2006, 11:33
von jens

Verfasst: Freitag 18. August 2006, 12:10
von droptix
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?

Verfasst: Freitag 18. August 2006, 13:03
von HWK
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

Verfasst: Freitag 18. August 2006, 15:05
von droptix
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!

Nachfragen

Verfasst: Samstag 19. August 2006, 08:29
von droptix
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())

Verfasst: Samstag 19. August 2006, 14:55
von jAN
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()

Verfasst: Samstag 19. August 2006, 15:12
von HWK
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

Verfasst: Samstag 19. August 2006, 15:31
von HWK
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")])) 

Funzt

Verfasst: Montag 21. August 2006, 11:32
von droptix
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...

Verfasst: Montag 21. August 2006, 12:26
von 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.

Klingt logisch

Verfasst: Montag 21. August 2006, 13:04
von droptix
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:

Verfasst: Montag 21. August 2006, 14:14
von 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"