0

I have an issue with this tkinter dropdown window. When running it by itself the code runs great, but when I run it as part of a larger code, the script gets stuck at this step unless I restart the kernel before every run. As long as I restart the kernel before running the script, the code works. How can I fix this issue and have the script run without having to restart the kernel before every run?

from tkinter import *

OPTIONS = [
"Physician 1",
"Physician 2",
"Physician 3"
]

master = Tk()
master.title("Physician Name")
master.geometry('300x200')
master['bg'] = '#add8e6'

variable = StringVar(master)
variable.set(OPTIONS[0]) # default value

w = OptionMenu(master, variable, *OPTIONS)
w.pack()

def ok():
    global name
    name =variable.get()
    print (name)
    master.destroy()

button = Button(master, text="OK", command=ok)
button.pack()

mainloop()

Update:

I use tkinter to choose file:

# GUI.py
from tkinter.filedialog import askopenfilename
import tkinter as tk

# Create the window and hide it
root = tk.Tk()
root.withdraw()

# Now you are free to popup any dialog that you need
filetypes = (("PDF file", "*.pdf"), ("All files", "*.*"))
filepath = askopenfilename(filetypes=filetypes)

# Now use the filepath
import re
import pdfplumber
import pandas as pd
from collections import namedtuple

lines = []

with pdfplumber.open(filepath) as pdf:
    pages = pdf.pages
    for page in pdf.pages:
        text = page.extract_text()
#        print(text)

# Destroy the window
root.destroy()

Then I have the code posted above where I have a dropdown menu

And finally I use this code to prompt the user to choose the name of the final file:

from tkinter import filedialog
root = tk.Tk()
root.withdraw()

pdfPath = filedialog.asksaveasfilename(defaultextension = "*.pdf", filetypes = (("PDF Files", "*.pdf"),))
if pdfPath: #If the user didn't close the dialog window
    pdfOutputFile = open(pdfPath, 'wb')
    pdfWriter.write(pdfOutputFile)
    pdfOutputFile.close()
    pdf1File.close()
    pdf2File.close()
Cristian
  • 93
  • 1
  • 7
  • start this script in its own process or thread, the reason for "getting stuck" is because `mainloop()` (which should be used as a method not as a function: `master.mainloop()`) doesn't allow any code after it execute until the instance of `Tk` (don't know which one: either the last or all or sth) is destroyed (in other words, `mainloop` is a while True loop) – Matiiss Jul 22 '21 at 20:00
  • @Matiiss Starting it in its own thread can be a bad idea. The `mainloop` that's there will try to handle events coming from other `tkinter` windows. That can cause real problems. Look at [this](https://stackoverflow.com/q/67007447/11106801) to see why you only need 1 `mainloop` in your whole code. – TheLizzard Jul 22 '21 at 20:02
  • 2
    If it's part of a bigger program that uses other `Tk()` windows, you only need 1 `mainloop` to handle the events from all windows. For more info please look [here](https://stackoverflow.com/q/67007447/11106801) – TheLizzard Jul 22 '21 at 20:03
  • @TheLizzard I understand that, but if it were alone in the thread (because I assumed that the larger code is not tkinter related) it would run fine, and I just remembered (from trying to create the video player) that tkinter cannot be run in another process either because it is not pickleable (in another process as in `multithreading.Process`) – Matiiss Jul 22 '21 at 20:04
  • @Matiiss Assuming that the other code doesn't use `tkinter`, your comment is right but I think it's unlikely that OP only used `tkinter` for this window. Also BryanOakley wrote: "*Tkinter widgets can't span processes. All access to tkinter widgets must be from within the same process*" [here](https://stackoverflow.com/a/68412417/11106801) – TheLizzard Jul 22 '21 at 20:09
  • I do have multiple tkinter codes. I only use mainloop once though... – Cristian Jul 22 '21 at 20:09
  • 1
    @Cristian Look at `Toplevel`. I think that in this case it will be easier if you used `Toplevel` instead of `Tk` for your second window. Can you please post a short description of your whole project? – TheLizzard Jul 22 '21 at 20:10
  • I'll update my question with the rest of the tkinter code. – Cristian Jul 22 '21 at 20:12
  • also: I strongly advise against using wildcard (`*`) when importing something, You should either import what You need, e.g. `from module import Class1, func_1, var_2` and so on or import the whole module: `import module` then You can also use an alias: `import module as md` or sth like that, the point is that don't import everything unless You actually know what You are doing; name clashes are the issue. and this is especially important for larger projects – Matiiss Jul 22 '21 at 20:12
  • I updated my question. So the idea of the script is to extract information from a pdf and create a word doc summary with the information needed. I use the dropdown to fill out a word template – Cristian Jul 22 '21 at 20:17
  • @Matiiss to be honest i'm not sure what I need, that's why I used (*)...I know it's not the best practice, but that's all I got so far...I'll try and see what I can do about it – Cristian Jul 22 '21 at 20:20
  • For the tkinter code that gives me trouble, even when the kernel is not restarted, the window popus up and allows me to make a selection. The code gets stuck once I press "ok" and the window dissapears and the selection is not printed out – Cristian Jul 22 '21 at 20:27
  • try making it `master.mainloop()` maybe that helps, also strange that the variable is not printed out (and also seems that there is no need for `global name`) – Matiiss Jul 22 '21 at 20:31
  • I tried to make it master.mainloop() and it didn't help – Cristian Jul 22 '21 at 20:36
  • could it be that the last tkinter i use (from tkinter import filedialog) never gets closed properly? – Cristian Jul 22 '21 at 20:40
  • looks like the selection gets printed out...my bad. but the cell still gets stuck. So the issue should be somewhere after that correct? @Matiiss – Cristian Jul 22 '21 at 20:50
  • possibly, how do you run the other scripts? are they all in the same file, you import them or run them using `subprocess` or sth? – Matiiss Jul 22 '21 at 20:53
  • I run everything in a jupyter notebook@Matiiss – Cristian Jul 22 '21 at 20:56
  • actually it would be great if you provided a [mre], in short that basically means the least amount of code that can be directly copied and run and will produce the same issue, writing this smaller amount of code may also help you find the issue, because right now I see three separate scripts that in this state seem to run fine (on their own and I see no connection between them (like imports and stuff)) – Matiiss Jul 22 '21 at 20:57
  • I'll see what i can do about that...It's kinda difficult since the program is super long and i'm not sure where the issue is coming from – Cristian Jul 22 '21 at 21:03
  • Could I just automatically restart the kernel at the end of each run? would that work?@Matiiss – Cristian Jul 22 '21 at 21:09
  • alright. I found the issue. I was missing the "root.destroy()" on my last tkinter used. Thanks everyone for the help! – Cristian Jul 22 '21 at 21:25

0 Answers0