Home > Blockchain >  Python - tkinter askopenfilename function somehow stays active while selecting the file "direct
Python - tkinter askopenfilename function somehow stays active while selecting the file "direct

Time:07-07

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.

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.

CodePudding user response:

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()
  • Related