I am following this tutorial to try and get an image to show up in a window with pysimplegui. https://www.youtube.com/watch?v=KtlGrgWf6Y8
import PySimpleGUI as sg
import os
layout = [
[sg.Image(filename='test_image_2.png')],
[sg.Button('Exit')]
]
window = sg.Window("Image Viewer", layout)
while True:
event, values = window.read()
if event == "Exit" or event == sg.WIN_CLOSED:
break
window.close()
I use the same code that the teacher uses, and the same image file and saved in the same folder as the python file.
When i run the code, I get the following window pop up:
error pop up window
I cannot understand why this would be showing. Do i need to save the image file to a different location? Or is it something else?
When I run the sample code below and click on the button, the GUI window shows not responding? Maybe because The GUI is waiting for the subprocess.run() to finish, because when I close the browser that is opened by the GUI, it is not responding anymore. How can I use the GUI when using subprocess.run()? Thanks.
Here is my sample code:
import PySimpleGUI as sg
import subprocess
layout = [
[sg.Button('Open Browser', key="ob")]
]
window = sg.Window('Metamask Accounts Opener', layout, element_justification='c', size=(400, 400))
while True:
event, values = window.read()
if event == sg.WIN_CLOSED or event == 'Exit': # if user closes window or clicks cancel
break
if event == "ob":
subprocess.run('"C:/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe" --remote-debugging-port=9222 -- "%1"')
window.close()
subprocess.run waits for the process to finish. You need to use Popen in order to not wait and just run in the background.
Popen(['"C:/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe"' ,"--remote-debugging-port=9222","--","%1"])
I want to create application with taskbar/system-tray icon. Crossplatform. OSX, Windows, Linux (Ubuntu/Centos/Mint/Manjaro and other popular distros).
This app should detect keyboard input and react to it. Basically do some actions on specific keys. Example: user wants to play some music, presses shift+ctrl+p. Music starts playing.
I know that Kivy capable of detecting
For the "cross-platform system-tray" thingy - I don't think this is entirely possible without some truly cross-platform framework like Elektron or something, which can give ability to use system-tray/taskbar feature.
For the detecting mouse even when window is not focused - use pynput with asyncio (example for kivy + asyncio in their official repository). Basically: you can detect keyboard events even when app is not focused with background working code with asyncio. Then it will detect every keystroke.
import PySimpleGUI as sg
from psgtray import SystemTray
"""
A System Tray Icon courtesy of pystray and your friends at PySimpleGUI
Import the SystemTray object with this line of code:
from psgtray import SystemTray
Key for the system tray icon is:
tray = SystemTray()
tray.key
values[key] contains the menu item chosen.
One trick employed here is to change the window's event to be the event from the System Tray.
Copyright PySimpleGUI 2021
"""
def main():
menu = ['',
['Show Window', 'Hide Window', '---', '!Disabled Item', 'Change Icon', ['Happy', 'Sad', 'Plain'], 'Exit']]
tooltip = 'Tooltip'
layout = [[sg.Text('My PySimpleGUI Celebration Window - X will minimize to tray')],
[sg.T('Double clip icon to restore or right click and choose Show Window')],
[sg.T('Icon Tooltip:'), sg.Input(tooltip, key='-IN-', s=(20, 1)), sg.B('Change Tooltip')],
[sg.Multiline(size=(60, 10), reroute_stdout=False, reroute_cprint=True, write_only=True, key='-OUT-')],
[sg.Button('Go'), sg.B('Hide Icon'), sg.B('Show Icon'), sg.B('Hide Window'), sg.Button('Exit')]]
window = sg.Window('Window Title', layout, finalize=True, enable_close_attempted_event=True)
tray = SystemTray(menu, single_click_events=False, window=window, tooltip=tooltip, icon='cogent_logo.png')
tray.show_message('System Tray', 'System Tray Icon Started!')
sg.cprint(sg.get_versions())
while True:
event, values = window.read()
# IMPORTANT step. It's not required, but convenient. Set event to value from tray
# if it's a tray event, change the event variable to be whatever the tray sent
if event == tray.key:
sg.cprint(f'System Tray Event = ', values[event], c='white on red')
event = values[event] # use the System Tray's event as if was from the window
if event in (sg.WIN_CLOSED, 'Exit'):
break
sg.cprint(event, values)
tray.show_message(title=event, message=values)
if event in ('Show Window', sg.EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED):
window.un_hide()
window.bring_to_front()
elif event in ('Hide Window', sg.WIN_CLOSE_ATTEMPTED_EVENT):
window.hide()
tray.show_icon() # if hiding window, better make sure the icon is visible
# tray.notify('System Tray Item Chosen', f'You chose {event}')
elif event == 'Happy':
tray.change_icon(sg.EMOJI_BASE64_HAPPY_JOY)
elif event == 'Sad':
tray.change_icon(sg.EMOJI_BASE64_FRUSTRATED)
elif event == 'Plain':
tray.change_icon(sg.DEFAULT_BASE64_ICON)
elif event == 'Hide Icon':
tray.hide_icon()
elif event == 'Show Icon':
tray.show_icon()
elif event == 'Change Tooltip':
tray.set_tooltip(values['-IN-'])
tray.close() # optional but without a close, the icon may "linger" until moused over
window.close()
if __name__ == '__main__':
main()
If you're willing to depart from Kivy and use another framework, PySimpleGUI has a System Tray capability (at least for Windows, and perhaps Linux/Mac) when running the tkinter version. The PySimpleGUIQt port has a more "official" System Tray feature.
The GitHub Repo PySimpleHotkey is one example of how to use the psgtray package to make a hotkey program.
https://github.com/PySimpleGUI/PySimpleHotkey
I am trying to automate the exiting operation on one of the apps. The app's icon is located in the taskbar. I was successfull in opening that icon's context menu with the modified code that I have found on stackoverflow:
import pywinauto
from pywinauto.application import Application
import time
app= "Service is enabled."
app = Application(backend="uia").connect(path="explorer.exe")
st = app.window(class_name="Shell_TrayWnd")
t = st.child_window(title="Notification Chevron").wrapper_object()
t.click()
time.sleep(1)
list_box = Application(backend="uia").connect(class_name="NotifyIconOverflowWindow")
list_box_win = list_box.window(class_name="NotifyIconOverflowWindow")
list_box_win.wait('visible', timeout=30, retry_interval=3)
# time.sleep(1)
appOpened= list_box_win.child_window(title = app)
appOpened.click_input(button = "right")
After the execution of the code above I get to the point when the context menu is opened:
The next thing that I want to do is to click on Exit, I have tried doing it by specifying the mouse click coordinates, but I have noticed that the position of the parent icon is changing from time to time.
What I would like to do is to get the handle on the Exit button and send click automatically.
------Edit-------
The icon is located in the hidden icons
So you want to access to the right click context menu. As said in this answer, you can do something like :
listbox.PopupMenu["Exit"].set_focus().click_input()
Is it possible to automatically activate the main window of a tkinter app? I am using Yosemite on a Mac. When the window comes up, the title bar is grayed out, and I have to click on the window before it will respond to events. The Tk manual says that event generate, "Generates a window event and arranges for it to be processed just as if it had come from the window system." I tried generating a <Button-1> event, but it had no effect. The manual goes on to say, "Certain events, such as key events, require that the window has focus to receive the event properly." I tried focus_force, but it didn't work either.
Is it possible to do what I want? Is this a Mac peculiarity? In the code below, the text changes as the mouse cursor enters and leaves the label, but the app is unresponsive until you click on the window.
import tkinter as tk
root = tk.Tk()
def visit(event):
kilroy['text'] = 'Kilroy was here.'
def gone(event):
kilroy['text'] = 'Kilroy has left the building'
def startup():
root.focus_force()
root.event_generate('<Button-1>')
frame = tk.Frame(root, width=500,height=100)
kilroy = tk.Label(frame, text="Kilroy hasn't been here.", width = 50)
kilroy.grid(row=0,column=0)
frame.grid(row=0,column=0)
kilroy.grid_propagate(0)
frame.grid_propagate(0)
kilroy.bind('<Enter>', visit)
kilroy.bind('<Leave>', gone)
root.after(100,startup)
root.mainloop()