2017-05-04 2 views
0

Ich versuche, ein benutzerdefiniertes Texteingabefeld zu erstellen, das ein Texteingabefeld in der Mitte hat und die Benutzereingabe zurückgeben kann. Ich versuche speziell etwas zu machen, das in andere Programme importiert und wiederverwendet werden kann. Meine aktuelle Iteration verwendet eine "Inputdialog" -Klasse, die gut funktioniert, um die Eingabe zu erhalten, wenn sie in ihrer eigenen .py-Datei ist. Wenn ich jedoch versuche, das Modul in ein anderes Skript zu importieren, tut die "ok" -Schaltfläche scheinbar nichts "button wirft einen" ImportError: kann den 'Inputdialog' Fehler nicht importieren, nachdem das Popup geschlossen wurde. Python Tkinter benutzerdefinierte msgbox schlägt während des Imports fehl

Das folgende ist mein Code, der zur Zeit, wenn laufen als Standalone-Skript funktioniert:

from tkinter import * 

class inputdialog: 
    def __init__(self): 
     self.value = None 
     self.root = Tk() 
     self.root.withdraw() 
     self.top = Toplevel(self.root) 


     Label(self.top, text="Value").pack() 
     self.e = Entry(self.top) 
     self.e.pack(padx=5) 

     b = Button(self.top, text="OK", command=self.ok) 
     b.pack(pady=5, padx=5, side="right") 
     self.root.mainloop() 

    def ok(self): 
     self.value = self.e.get() 
     self.root.destroy() 

if __name__ == "__main__": 
    test = inputdialog() 
    print(test.value) 

Das Folgende ist, wie ich dieses Modul in ein anderes Programm importiert haben, die derzeit nicht arbeiten:

if __name__ == "__main__": 
    # These two lines below are needed to make sure that "askopenfilename" 
    # doesn't show it's top level tkinter window 
    root = Tk() 
    root.withdraw() 
    entdbemp = askopenfilename(title="Please select a file: ") 

    # Here is my non-working module call 
    master = inputdialog() 
    print(master.value) 

Warum sollte meine Schaltfläche "OK" beim Importieren nicht mehr funktionieren? Gibt es eine Möglichkeit, meinen Code zu reparieren, damit er importiert werden kann? Gibt es eine bessere Möglichkeit, ein importierbares Texteingabemodul mit tkinter zu erstellen?

+0

Ein Problem ist, dass Sie zwei Instanzen von 'Tk' erstellen. Tkinter hat genau eine Instanz von 'Tk'. –

Antwort

2

Das Problem hat nichts mit dem Importieren zu tun. Das Problem ist, dass Sie in Ihrem zweiten Beispiel Tk() zweimal aufrufen: einmal in jeder Datei. Wenn Sie 'destroy' aufrufen, entfernen Sie nur die GUI vom Bildschirm, Sie verlassen die Hauptschleife nicht.

Um diese Arbeit zu machen, um die Linien entfernen müssen, die eine Wurzel in der inputdialog Klasse zu erstellen, bewegen Sie den mainloop() Aufruf zu einem Punkt nach der Klasse starten, und dann rufen Sie die quit Methode für die Top-Level-Fenster (nicht die Wurzel Fenster):

from tkinter import * 
class inputdialog: 
    def __init__(self, master=None): 
     self.value = None 
     self.top = Toplevel(master) 

     Label(self.top, text="Value").pack() 
     self.e = Entry(self.top) 
     self.e.pack(padx=5) 

     b = Button(self.top, text="OK", command=self.ok) 
     b.pack(pady=5, padx=5, side="right") 

    def ok(self): 
     self.value = self.e.get() 
     self.top.quit() 

if __name__ == "__main__": 
    root = Tk() 
    root.withdraw() 
    master = inputdialog(root) 
    root.mainloop() 
    print(master.value) 

Wenn Sie ordentlich und richtig sein: anstatt eine Klasse zu machen, die gerne in OOP und GUIs wir eine Unterklasse machen um eine andere Klasse wickelt: auch

import tkinter as tk 

class inputdialog(tk.Toplevel): 
    def __init__(self, master=None): 
     tk.Toplevel.__init__(self, master) 

     self.value = None 

     tk.Label(self, text="Value").pack() 
     self.e = tk.Entry(self) 
     self.e.pack(padx=5) 

     b = tk.Button(self, text="OK", command=self.ok) 
     b.pack(pady=5, padx=5, side="right") 

    def ok(self): 
     self.value = self.e.get() 
     self.quit() 

if __name__ == "__main__": 
    root = tk.Tk() 
    root.withdraw() 
    master = inputdialog(root) 
    root.mainloop() 
    print(master.value) 

, Wildcard-Importe (from module import *) sind hässlich und gegen PEP8; benutze sie nicht.

BTW, das easygui Paket hat all dies bereits getan; Vielleicht möchten Sie das nur installieren und verwenden.

+0

Danke! Ich werde es versuchen, wenn ich nach Hause komme. Ich mache nicht viel, werde mich daran erinnern, in Zukunft eine Unterklasse zu machen. Ich dachte, dass das doppelte Tk() s ein Problem sein könnte, aber war nicht sicher, wie man das mildert. Was den Wildcard-Import angeht, habe ich den Basiscode aus einem hastigen Beispiel genommen und ihn nie repariert (sorry!) – TheEmpireNeverEnded

+0

Hey @Novel, ich habe deinen Code oben kopiert und die gleichen Probleme bestehen immer noch, aber dann habe ich deinen Code auf einen anderen kopiert meine PCs und es hat gut funktioniert. Sehr eigenartig. Ich werde dies als beantwortet markieren, weil es zu funktionieren scheint; Ich denke, ich habe etwas mit meiner Umwelt nicht in Ordnung. – TheEmpireNeverEnded

Verwandte Themen