Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Python – tkinter askopenfilename function somehow stays active while selecting the file "directly" doesn't

I’m not a programmer so admittingly my title might be a bit off.

I have a program where I select an IFC-file (used in the construction industry, which contains data about the geometry and data connected to the objects in the 3D drawing) and then a dialog opens where I can add a GUID (an identifier) and search for all the information related to that object in the IFC-file, which I then print in the command prompt.

A minor issue which annoys me a bit is that the when is select the file in a more flexible way, using askopenfilename, the function seems to stay active or in a loop after I close the later opening dialog, so that I have to end the process using CTRL+C.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

I post the entire code as I don’t know if there is something else which causes it:

#imports to search for files
import os

# imports tkinter for selection purposes, so that one can select the files instead of reading in them automaticall from a directory
import tkinter as tk
from tkinter.filedialog import askopenfilename

#importing the counter to counte the occurences in a list
from collections import Counter

#importing regex functionality to check values
import re

#this is the numbering, for example #433, #4781 etc, that we either want to look for or change - now it looks for up to a number of length 7
regexIFCnumbers = '#\d{1,7}'


tk.Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
file1 = askopenfilename(initialdir=os.getcwd()) # show an "Open" dialog box and return the path to the selected file - this in the current directory where we'll start looking

file1Name = (os.path.basename(file1)) #only the file's name
    
#read files
def readFile(file):
    x = []
    f = open(file, 'r') 
    x = f.readlines()
    f.close()
    return(x)

x1 = readFile(file1)

#checks the GUIDs
def checkGUID(GUID, IFC):
    A = []
    for row in IFC:
        if GUID in row:
            #print(re.findall(regexIFCnumbers, row))
            
            A.extend(re.findall(regexIFCnumbers, row))
            return(A)

#the numbering is not perfectly ordered and varies in some places, so need to index it all to find the correct lines
def indexIFC(IFC):
    A = []
    for index, row in enumerate(IFC):
        if re.findall('^#', row): #starts with a hash #
            B = re.findall(r'\#\w+', row)[0]
            A.append([B, index])
            
    return(A)


def recurseThrough(inputList, IFC, checkedList, fullList, indexednumbersList):
    for item in inputList:
        for hashvalueList in indexednumbersList:
            if item == hashvalueList[0]:
                positionInIFC = hashvalueList[1]

        if re.search('^'+item, IFC[positionInIFC]) and item not in checkedList: #if the row begins with the number item in the list
            checkedList.append(item)
            fullList.append(IFC[positionInIFC])
            recurseThrough(re.findall(regexIFCnumbers, IFC[positionInIFC])[1:], IFC, checkedList, fullList, indexednumbersList) #recurses through the next list
    return(fullList)
    

from os import system, name
 
def clear():
    if name == 'nt':
        _ = system('cls')

def runTheGUIDCheck(setValue):
    inputValue = str(setValue)
    print(inputValue)
    clear()
    
    try:
        B1 = checkGUID(inputValue, x1) #This returns a list with for example [#122, #5, #7889]

        checkedList = [] #the list of already checked items
        fullList = []

        indexedIFClist1 = indexIFC(x1)

        #run the function with the initial input, sending in empty array as well as they should be empty/none at the start
        outList1 = recurseThrough(B1, x1, [], [], indexedIFClist1)

        for index, item in enumerate(outList1):
            print(index, item.strip())
        
        return None
    
    except:
        print("inserted GUID not found or didn't work")
        

        
#dialog
dialog = tk.Tk()

dialog.geometry('500x200')

t1 = tk.Label(dialog, text = 'Check GUID')
t1.grid(row = 0, column = 0, sticky = 'w')

testGUIDAttributes = tk.Entry(dialog, width = 40)
testGUIDAttributes.grid(row = 0, column = 1, columnspan = 50)

button = tk.Button(dialog, text='Run GUID', command = lambda: runTheGUIDCheck(testGUIDAttributes.get()))
button.grid(row = 5, column = 0, sticky = 'w')

dialog.mainloop()

If I select the file directly like this…

file1 = 'thefile.ifc'

instead of with the above this…

tk.Tk().withdraw() # we don't want a full GUI, so keep the root window from appearing
file1 = askopenfilename(initialdir=os.getcwd()) # show an "Open" dialog box and return the path to the selected file - this in the current directory where we'll start looking

then this issue doesn’t come up and the command prompt will accept new commands after I close the dialog which is "created" at the end.

>Solution :

Since you have created two instances of Tk(): one in the line tk.Tk().withdraw() and one in the line dialog = tk.Tk(), so the line dialog.mainloop() will not return until both windows are closed. However you cannot close the withdrawn window because it is invisible.

You should create only one instance of Tk(), hide it and then show the file dialog. Then show it back and proceed as normal:

...
# create the main window and hide it initially
dialog = tk.Tk()
dialog.withdraw()
file1 = askopenfilename(initialdir=os.getcwd()) # show an "Open" dialog box and return the path to the selected file - this in the current directory where we'll start looking
...
# show back the main window
dialog.deiconify()
dialog.geometry('500x200')
...
dialog.mainloop()
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading