2

je primary.py:Tkinter ouvre plusieurs fenêtres de l'interface graphique lors de la sélection de fichiers avec multitraitement, quand une seule fenêtre doit exister

from tkinter import * 
from tkinter.filedialog import askopenfilename 
from tkinter import ttk 
import multiprocessing as mp 
import other_script 

class GUI: 
    def __init__(self, master): 
     self.master = master 

def file_select(): 

    path = askopenfilename() 

    if __name__ == '__main__': 
     queue = mp.Queue() 
     queue.put(path) 
     import_ds_proc = mp.Process(target=other_script.dummy, args=(queue,)) 
     import_ds_proc.daemon = True 
     import_ds_proc.start() 

# GUI 
root = Tk() 

my_gui = GUI(root) 

# Display 

frame = Frame(width=206, height=236) 
frame.pack() 

ttk.Button(frame, text="Select", command=file_select).pack(anchor='nw') 

# Listener 

root.mainloop() 

Et other_script.py:

def dummy(parameter): 
    pass 

Lors de l'exécution de cette, lors de la sélection d'un fichier, une seconde fenêtre GUI apparaît. Pourquoi? C'est un comportement indésirable, je veux plutôt dummy pour fonctionner.

Merci.

+0

Utiliser la racine .withdraw() pour éliminer la fenêtre Tk() (que vous envoyez à l'interface graphique). askopenfilename() ouvre sa propre fenêtre, qui est la deuxième que vous voyez http://effbot.org/tkinterbook/wm.htm Notez que "dummy" sera exécuté après le retour de askopenfilename. –

Répondre

1

Tout comme avec multiprocessing, vous devez placer le code à faire avec tkinter et faire de votre fenêtre dans le point d'entrée de votre programme (de sorte qu'il ne soit pas exécuté plus d'une fois par un autre processus).

Cela signifie déplacer la clause if __name__ == "__main__" vers le bas de votre programme et placer le code associé à tkinter à la place. Le point d'entrée de votre multiprocessing sera toujours protégé comme il est appelé après un événement, qui est défini dans le point de départ.

Edit: Le point d'entrée est l'endroit où votre programme est entré à partir, normalement quand vous dites if __name__ == "__main__".

En déplaçant le code tkinter dans le point d'entrée, je veux dire quelque chose comme ceci:

if __name__ == "__main__": 
    root = Tk() 
    my_gui = GUI(root) 
    frame = Frame(width=206, height=236) 
    frame.pack() 
    ttk.Button(frame, text="Select", command=file_select).pack(anchor='nw') 
    root.mainloop() 

(Au « bas » de votre programme, soit après toutes les fonctions sont définies.)

+0

J'apprécie la réponse, mais j'ai du mal à la déballer. J'ai les questions suivantes: 1. Qu'est-ce qui constitue le «bas» du programme? Est-ce après root.mainloop()? 2. Lorsque vous faites référence au déplacement de la clause 'if __name__ ==" __main __ "', de quoi parlez-vous? Tout ce bloc de code, ou toute cette fonction? Il semble au moins que queue.put (chemin) devrait rester où il est. 3. Lorsque vous vous référez à placer le code à faire avec 'tkinter' dans" là "à la place, où et quoi" là "? Est-ce que c'est dans la définition? Je ne vois pas pourquoi le code 'tkinter' serait là. – user1318135

+0

(suite) 4. Quand vous parlez d'un événement défini dans le point de départ, que voulez-vous dire? 5. Enfin, vous vous référez au code à faire avec 'tkinter' plusieurs fois ... qu'est-ce que cela signifie en particulier? Et quel est le point d'entrée? – user1318135

+1

@ user1318135 Voir ma modification. Pour plus d'informations sur le point d'entrée, jetez un oeil à ceci: https://docs.python.org/2/library/multiprocessing.html#windows – SneakyTurtle