Start Python script GUI minimized / in Windows Tray | Tkinter - python

I´ve built a simple GUI app, and I´m playing with pystray.
Actually, my script starts as usual, the first thing you see is the GUI.
If you klick on exit, the GUI minimize, and the tray Icon spawns.
For now, i search a way to start my script in this "tray Mode"
here are some informations:
class Hauptfenster:
# Define a function for quit the window
def quit_window(icon, item):
icon.stop()
fenster.destroy()
# Define a function to show the window again
def show_window(icon, item):
icon.stop()
fenster.after(0, fenster.deiconify())
# Hide the window and show on the system taskbar
#staticmethod
def hide_window():
fenster.withdraw()
image = Image.open(os.path.join(application_path, iconFile))
menu = (item('Beenden', Frontend.Hauptfenster.quit_window), item('Einstellungen', Frontend.Hauptfenster.show_window))
icon = pystray.Icon("name", image, "Quicksafe", menu)
icon.run()
Please ask me if you need some more Information and Thanks a lot !
Best regards
Background:
My programm should lay in the autostart of win10 , but i dont want to minimize the window each time i restart my pc

I just added my method hide_window to my main function,
when script starts, you see something moving on to screen for 2ms.. but it disapears very quick... so thats something I can live with

Related

Pyside: Opening a new window with picture

I have created a UI that can be launched inside Maya. My class for this window inherits from QDialog. I want to have a button that will open a jpg into a new window, and then it closes with another button. While this other window is open I would like to still be able to interact with the main window. Is it possible to do this? How would I go about launching this new window?
You can use this code to get what you want. I tested it in Maya 2016.5 on macOS. Works fine!
import maya.cmds as cmds
def loadSecondWindow(*args):
window = cmds.window()
cmds.paneLayout()
cmds.image(image='/Users/swift/Desktop/scientist01.jpg')
cmds.showWindow(window)
def deleteSecondWindow(*args):
if (cmds.window('window2', exists=True)):
cmds.deleteUI('window2')
cmds.window(width=200)
cmds.columnLayout(adjustableColumn=True)
cmds.button(label='Window with Picture', command=loadSecondWindow)
cmds.button(label='Delete Window', command=deleteSecondWindow)
cmds.showWindow()

Tkinter: Window flash when attempting to click away

Ive been trying to do this for a while now, but haven't figured out a way to do it.
I have a tkinter script, that creates a popup window when a button is pressed. However I don't want the user to be able to click away from this window to any previous windows created. I have got this working with root.grab_set(), however there is no indication to the user that they must stay on that window.
class popup(object):
def __init__(self, parent):
self.root=Toplevel(parent)
self.root.grab_set() #prevents the user clicking on the parent window
#But the window doesnt 'flash' when an attempt to click away is made
For example, when you have a window created by the filedialogue module, if you attempt to click onto another window the filedialogue window stays on top and has a 'flashing' animation to let the user know they cant click away. Is there a way I can reproduce this effect? Going through the source of filedialogue hasn't been fruitful for me, and neither have Google searches.
The simplest way i can think to do this is to use an event and the focus commands, along with the windows bell command:
#!python3
import tkinter as tk
class popup(object):
def __init__(self, parent):
self.root=tk.Toplevel(parent)
self.root.title("Popup")
self.root.bind("<FocusOut>", self.Alarm)
def Alarm(self, event):
self.root.focus_force()
self.root.bell()
main = tk.Tk()
main.title("Main")
pop = popup(main)
main.mainloop()
Here's a solution for Windows that uses FlashWindowEx from the user32 dll. You need to pass a FLASHWINFO object to it. The grab_set makes sure the popup window stays in focus and disables any widgets in the main window, making the popup transient makes sure it's always on top of the master. The <Button-1> event is used to check mouse clicks, and winfo_containing checks if another window than the popup is clicked. I then set the focus back to the popup and flash the window in focus (which then always is the popup).
You need pywin32 to use this.
import Tkinter as tk
from ctypes import *
import win32con
class popup(object):
def __init__(self, parent):
self.parent = parent
self.root=tk.Toplevel(self.parent)
self.root.title("Popup")
self.root.grab_set()
self.root.transient(self.parent)
self.root.bind("<Button-1>", self.flash)
def flash(self, event):
if self.root.winfo_containing(event.x_root, event.y_root)!=self.root:
self.root.focus_set()
number_of_flashes = 5
flash_time = 80
info = FLASHWINFO(0,
windll.user32.GetForegroundWindow(),
win32con.FLASHW_ALL,
number_of_flashes,
flash_time)
info.cbSize = sizeof(info)
windll.user32.FlashWindowEx(byref(info))
class FLASHWINFO(Structure):
_fields_ = [('cbSize', c_uint),
('hwnd', c_uint),
('dwFlags', c_uint),
('uCount', c_uint),
('dwTimeout', c_uint)]
main = tk.Tk()
main.title("Main")
pop = popup(main)
main.mainloop()
As it is now, the flash only occurs when the main window's body is clicked, so clicking the title bar just returns the focus to the popup without flashing. To make it fire also when that happens you could try using the <FocusOut> event, but you would have to make sure it only happens when the focus passes to the main window, but it never really does since the grab_set is used. You might want to figure that out, but as it is now it works quite well. So it's not perfect, but I hope it helps.

How to find the active PyQt window and bring it to the front

I'm new to PyQt. I have been searching on how to find the window of my PyQt app which is currently open and bring it to the front. This far all I've found is an example in which pywin32 was used(thus windows specific). I wanted to ask if there is a platform-independent way I can achieve the objective. Any help would be much appreciated.
Here is my code. The activateWindow() function is supposed to bring it to the front.
class TestApp(QtGui.QApplication):
def __init__(self, argv, key):
QtGui.QApplication.__init__(self, argv)
self._activationWindow=None
self._memory = QtCore.QSharedMemory()
self._memory.setKey(key)
if self._memory.attach():
self._running = True
else:
self._running = False
if not self._memory.create(1):
raise RuntimeError(
self._memory.errorString().toLocal8Bit().data())
def isRunning(self):
return self._running
def activationWindow(self):
return self._activationWindow
def setActivationWindow(self, activationWindow):
self._activationWindow = activationWindow
def activateWindow(self):
if not self._activationWindow:
return
self._activationWindow.setWindowState( self._activationWindow.windowState() & ~QtCore.Qt.WindowMinimized | QtCore.Qt.WindowActive)
self._activationWindow.raise_()
self._activationWindow.show()
self._activationWindow.activateWindow()
A complete, platform-indepenent solution is probably going to be beyond reach. Each of the platforms supported by Qt behaves in a different way, and activateWindow seems to be somewhat buggy.
To start with, here's what the Qt docs say about activateWindow:
This function performs the same operation as clicking the mouse on the
title bar of a top-level window. On X11, the result depends on the
Window Manager. If you want to ensure that the window is stacked on
top as well you should also call raise(). Note that the window must be
visible, otherwise activateWindow() has no effect.
and:
On Windows, if you are calling this when the application is not
currently the active one then it will not make it the active window.
It will change the color of the taskbar entry to indicate that the
window has changed in some way. This is because Microsoft does not
allow an application to interrupt what the user is currently doing in
another application.
For more confirming evidence of the difficulties, take a look at these threads on the Qt forum:
Bring window to front -> raise(), show(), activateWindow() don’t work on Windows
activateWindow() does not send window to front

Cannot access text entry box after reopen the GTK window

First of all, this issue is only happened in WIN7, and it is normally under raspberry pi (Debian Linux).
I have two window, the main window and a child window. The main window has a button which can activate the child window. The child window has a text entry box which can input the strings. The issue is when activate the child window at 1st time, the text entry box is functional. But when the child window is closed and re-opened, the text entry box seems disabled that cannot input any text into it, even set_text("xx") function cannot write any text into it.
The detailed steps are:
run the py script
click the button on main window to open the child window. I have tried with the below three methods, it seems they have same issue:
def on_button_clicked(self, widget, data=None):
self.child_window.present()
#self.child_window.show()
#self.child_window.show_all()
Now the child window is opened and the text entry box is functional, I can type any text into it.
Close the child window. I have bind the delete signal on to the child window. So every time the child window is closed, the below function will be executed, which will hide the current child window.
def on_WindowOfScanning_delete_event(self, widget, data=None):
self.child_window.hide()
return True
Now the main window is on focus and click the button to activate the child window again.
self.child_window.present()
Now the child window is appear, but the text entry box seems disabled.
Any one can help me on this issue? Appreciated for that..
The version information is: Python 2.7.3 GTK 2.24.2, and I use glade to manage the GUI interface.
================= The same question with a different example: =====================
http://www.pygtk.org/pygtk2tutorial/sec-TextEntries.html#entryfig
This link is the pygtk's official example. While running on my WIN7(64bit) system, the text entry box cannot be edited since the first time opening. But if you move mouse to activate other window, and turn back to this gtk window, the text entry box can be edited then. I am not sure if this is a pygtk's bug.
I have tried python 2.6.6 and 2.7.3 with pygtk2.24.2-all-in-one.
================= The solution to this issue: =====================
It seems no one have such kind of problem so I post my own solution.
1st, give up using the window.hide() function.
2nd, destroy the child window every time it finished its job, and re-init the gtk.Window again to invoke the child window. Here is a simple example:
#!/usr/bin/env python
import pygtk
pygtk.require( "2.0" )
import gtk
class PopupExample(gtk.Window):
def __init__( self ):
gtk.Window.__init__(self)
self.connect("destroy", lambda *w: gtk.main_quit())
button = gtk.Button("Popup Window")
button.connect("clicked", self.show_popup_window)
self.add(button)
def show_popup_window(self, button):
popup = gtk.Window()
popup.add(gtk.Entry())
popup.show_all()
if __name__ == "__main__":
pe = PopupExample()
pe.show_all()
gtk.main()
I encountered the same problem in gnucash and inkscape,
I solved this problem by going into Control Panel -> Locales and Languages and set format to English(US)

wxPython: how to make taskbar icon respond to left-click

Using wxPython, I created a taskbar icon and menu.
Everything works fine (in Windows at least) upon right-click of the icon: i.e., the menu is displayed, and automatically hidden when you click somewhere else, like on Windows' taskbar.
Now I do want to have the menu appear when the icon is left-clicked as well.
So I inserted a Bind() to a left-click in the Frame class wrapper, calling the CreatePopupMenu() of the taskbar icon:
import wx
class BibTaskBarIcon(wx.TaskBarIcon):
def __init__(self, frame):
wx.TaskBarIcon.__init__(self)
self.frame = frame
icon = wx.Icon('test_icon.ico', wx.BITMAP_TYPE_ICO)
self.SetIcon(icon, "title")
def CreatePopupMenu(self):
self.menu = wx.Menu()
self.menu.Append(wx.NewId(), "dummy menu ")
self.menu.Append(wx.NewId(), "dummy menu 2")
return self.menu
class TaskBarFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, style=wx.FRAME_NO_TASKBAR)
...
self.tbicon = BibTaskBarIcon(self)
wx.EVT_TASKBAR_LEFT_UP(self.tbicon, self.OnTaskBarLeftClick)
...
def OnTaskBarLeftClick(self, evt):
self.PopupMenu(self.tbicon.CreatePopupMenu())
...
def main(argv=None):
app = wx.App(False)
TaskBarFrame(None, "testing frame")
app.MainLoop()
This works fine, except that the menu does not disappear automatically when you click somewhere else on your screen. In fact, left-clicking multiple times on the icon creates multiple menus. The only way to hide the menu(s) is to click on one of its items (which you don't always want). I've looked at the available methods of TaskbarIcon, but I failed to be clear about which one to use to hide the menu (.Destroy() didn't work). Moreover, I don't know which event to bind it to (there is a EVT_SET_FOCUS, but I couldn't find any EVT_LOOSE_FOCUS or similar).
So, how to hide the menu upon losing focus?
EDIT: I've inserted a bit more code, to make it more clear
Ah, I've discovered what went wrong. In the statement
self.PopupMenu(self.tbicon.CreatePopupMenu())
I had bound the popup menu to the frame, instead of to the taskbar icon.
By changing it to:
self.tbicon.PopupMenu(self.tbicon.CreatePopupMenu())
all is working well now.
Thanks for all remarks
I think the problem here is that the PopupMenu is usually used in a program's context, not a little icon in the system tray. What that means is that in a normal frame, the popup menu would detect the click the you clicked off of it. Here, you are clicking outside of the wxPython program. Also, the PopupMenu is usually used with EVT_CONTEXT_MENU, not this taskbar event.
You can try wx.EVT_KILL_FOCUS and see if that works since it should theoretically fire when you click off the menu. Or you could ask on the official wxPython forum here: http://groups.google.com/group/wxpython-users/topics
Mike Driscoll
Blog: http://blog.pythonlibrary.org

Categories