Reputation: 69
I made a Python GUI application using tkinter. The problem I have is that you can run as many instances as you want. But I only want one instance to be running, if the application is already running and I click again EXE or shortcut, instead it should bring existing running application to the focus.
Upvotes: 4
Views: 1377
Reputation: 6820
Forgive the necromancy. For folks coming from a search engine looking for a way to do this within the StdLib, I have a similar solution to @tgikal that doesn't require win32gui:
from ctypes import WinDLL
import sys
APP_NAME = 'My app name' # this isn't totally necessary, it's just for readability
def instance_check():
U32DLL = WinDLL('user32')
# get the handle of any window matching 'APP_NAME'
hwnd = U32DLL.FindWindowW(None, APP_NAME)
if hwnd: # if a matching window exists...
# focus the existing window
U32DLL.ShowWindow(hwnd, 5)
U32DLL.SetForegroundWindow(hwnd)
# bail
sys.exit(0)
return True
def main():
if instance_check(): # if no other instance is found...
root = Root() # instantiate your tk app
root.mainloop() # run as usual
# etc.
if __name__ == '__main__':
main()
The idea is that this will check for a running instance of your app by name, focus it if it's found, then exit the current interpreter before the second instance is started.
Oh, and if like me you're curious about that magic number 5
in ShowWindow
, see the MDN docs here. The TL;DR is that the number is the nCmdShow
argument and 5
means:
Activates the window and displays it in its current size and position
I hope this helps!
Upvotes: 2
Reputation: 1680
I actually have a windows application that does this using pywin32
.
It looks for the application name, if it exists, it brings it to the front and closes the extra program.
version = "Program Name"
import win32gui
import sys
# Checks if there is a currently running program
# If there is, brings up that program
hwnd = win32gui.FindWindow(None, version)
if hwnd:
win32gui.ShowWindow(hwnd, 5)
win32gui.SetForegroundWindow(hwnd)
sys.exit(0)
Upvotes: 2
Reputation: 386240
A simple cross-platform trick is to write the process id (pid) of the first instance to a file in a known location (eg: my_program.pid in the system temporary directory). Each time you start up, check to see if that file exists. If it exists, read the pid and check if the process is running. If the process is still running, exit. If not, keep running and write your process id to the file. When the program that wrote the file exits, it should delete the file.
There are possible race conditions (eg: the running program could quit in the brief moment after checking but before your program decides to quit), but unless you're building a commercial-grade application, this is usually good enough.
Upvotes: 2
Reputation: 4132
I would use a lock file with e.g the filelock library. Create an arbitrary file: if the file is unlocked, launch the GUI and lock the file. If the file is locked, just exit.
Upvotes: 2