Search code examples
pythonwindowstkinterexepyinstaller

Python Pyinstaller exe opens multiple instance of tkinter window, Python Firebase [Video]


I have a scraping script of where im using tkinter for ui. When i build the exe(with pyinstaller) and open it it working well, But When i close it, it opens multiple instance of tkinter Window. I cant paste the full code. So i pasted all the tkinter code i am using.

Here is the Full code Github Gist here

import requests
from lxml import html
from tkinter import *
import tkinter as ttk
import re
import datetime
import os
from firebase import firebase
import hashlib
#import App as App
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import time


#Region Tk
root = Tk()
root['height'] = 400
root['width'] = 600
global firebase
firebase = firebase.FirebaseApplication('#######URL####',None)
f1 = Frame(root)
f1["height"] = root["height"]
f1["width"] = root["width"]
root.title("JD Scraper - Gear Up Studio ")
Label(f1,text = "Input Url : Example : https://www.justdial.com/Ahmedabad/Gyms ").grid(row=0,column = 0,)

def getBool(event):
    print(boolvar.get())
#Check Button
global boolvar
boolvar = BooleanVar()
boolvar.set(False)
boolvar.trace('w', lambda *_: print("The value was changed"))
cb = Checkbutton(f1, text = "Tele Phone number", variable = boolvar)
cb.bind("<Button-1>", getBool)
cb.grid(row=1, column=1)

global key_filled
key_filled = Entry(f1,width=50)
key_filled.grid(row=2,column=0)
key_filled.focus_set()
global activate_button
activate_button = Button(f1 , text="Active Now")
activate_button.bind("<Button-1>",activate_key)
activate_button.grid(row=2, column=1)


result = Label(f1, width=50)
result.grid(row=1,column=2)
global submit_button
submit_button = Button(f1 , text="Scrape Now")
submit_button.bind("<Button-1>",button_clicked)
submit_button.grid(row=1, column=0)
submit_button.config(state=NORMAL)
key_validation()
f1.pack()
root.mainloop()

Demo Video here


Solution

  • i was facing the exact the same problem with firebase and pyqt5. After many tries i examine the firebase library. In init there is close_process_pool() function which is called when program exits and close all the multiprocessing pools. In tkinter and pyqt case we dont need this function as all the process is the childs of main GUI thread so simple removing that function resolves the problem. Change the init file to this will resolve the issue.

    import atexit
    #from .async import process_pool
    from firebase import *
    
    
    '''
    @atexit.register
    def close_process_pool():
        """
        Clean up function that closes and terminates the process pool
        defined in the ``async`` file.
        """
        process_pool.close()
        process_pool.join()
        process_pool.terminate()
        '''