The issue is a combination of setting an icon on the action in the toolbar (or qpushbutton) and showing a qmessagebox when triggered. If I remove the icon, the message box displays. And if I remove the message box but keep the icon, the app stays open. The other odd thing is, if I add the icon to the push button but not the action, and click on the action, it still closes the app. The doubly odd thing is if I add main.qpush_button_clicked before qapplication.exec_(), the message box is displayed. However, the next time I click on either, it closes the app.
I have looked at multiple posts and some of the ideas were to use setQuitOnLastWindowClosed, but that did not fix the issue. I also implemented event to see what was happening. When I click on either of the items, it triggers a ChildAdded event, then closes.
Also, this only does not work when I use cx_Freeze on a Mac. I have not tried on Win. It works properly when run using Eclipse or from CLI.
Does anyone have any ideas on what might be causing this, or how to fix it besides not using icons.
The icon I used is from Android icon pack.
I can add the crash log if you need it.
class Main(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.qicon = QIcon('../ic_add_black_24dp_1x.png')
self.tool_bar = self.addToolBar('main')
qaction = QAction(self)
self.tool_bar.addAction(qaction)
qaction.setText('add')
qaction.setIcon(self.qicon)
qaction.triggered.connect(self.qpush_button_clicked)
qpush_button = QPushButton('add')
self.setCentralWidget(qpush_button)
qpush_button.setIcon(self.qicon)
qpush_button.clicked.connect(self.qpush_button_clicked)
def qpush_button_clicked(self, *args, **kwargs):
QMessageBox.critical(self, 'test', 'testing')
if __name__ == '__main__':
qapplication = QApplication(sys.argv)
main = Main()
main.show()
main.raise_()
qapplication.exec_()
And here is the setup file
name = 'dialog'
version = '0.1'
description = 'description'
packages = ('os',)
excludes = ('tkinter',)
include_files = ('ic_add_black_24dp_1x.png',)
build_exe = dict(packages=packages,
excludes=excludes,
include_files=include_files)
options = dict(build_exe=build_exe)
base = 'Win32GUI' if sys.platform == 'win32' else None
script = 'dialog.py'
executables = (Executable(script, base=base),)
setup(name=name,
version=version,
description=description,
options=options,
executables=executables)
PySide Version : 1.2.2
PySide Component: : (1, 2, 2, 'final', 0)
PySide Compiled Qt : 4.8.7
PySide Qt Component: (4, 8, 7)
Running Qt Version : 4.8.7
Related
I have a python script that I would like to run from the Windows 11/10 Right Click Context Menu in my documents folder
"C:\\Users\\me\\Documents\\PythonScripts\\main.py"
from PyQt6.QtWidgets import QApplication, QWidget
app = QApplication([])
window = QWidget()
window.setWindowTitle('My PyQt6 Application')
window.resize(400, 300)
window.move(100, 100)
window.show()
app.exec()
I created a python script that adds an item to the Right Click Context Menu in Windows 11 via registry.
But, The problem I am having is that when I try to click on "My Python Script" in the context menu, a pyqt6 window should pop up.
I tried running the exact command in terminal window
C:\Users\me\AppData\Local\Programs\Python\Python311\python.exe C:\Users\me\Documents\PythonScripts\main.py "%V"which works with no issues.
import winreg
menu_name = "My Python Script"
icon_path = "%SystemRoot%\\system32\\imageres.dll,3"
python = "C:\\Users\\me\\AppData\\Local\\Programs\\Python\\Python311\\python.exe"
command = f"{python} C:\\Users\\me\\Documents\\PythonScripts\\main.py \"%V\""
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT,
r"Directory\Background\shell",
0, winreg.KEY_WRITE)
menu_key = winreg.CreateKey(key, menu_name)
winreg.SetValueEx(menu_key, "Icon", 0, winreg.REG_SZ, icon_path)
winreg.SetValueEx(menu_key, "command", 0, winreg.REG_SZ, command)
winreg.CloseKey(menu_key)
winreg.CloseKey(key)
I found where the issue resided. I was adding the command key incorrectly. I needed to use command_key = winreg.CreateKey(menu_key, "command") for the command. Then add the value winreg.SetValueEx(command_key, "", 0, winreg.REG_SZ, command).
import winreg
# Name that will appear in the context menu
menu_name = "My Python Script"
# Path to the icon file
icon_path = "%SystemRoot%\\system32\\imageres.dll,3"
python = "C:\\Users\\me\\AppData\\Local\\Programs\\Python\\Python311\\python.exe"
# Path to the Python script and any command-line arguments
command = f"{python} C:\\Users\\me\\Documents\\PythonScripts\\main.py \"%V\""
# Open the registry key
key = winreg.OpenKey(winreg.HKEY_CLASSES_ROOT,
r"Directory\Background\shell",
0, winreg.KEY_WRITE)
# Create a new key for our menu item
menu_key = winreg.CreateKey(key, menu_name)
command_key = winreg.CreateKey(menu_key, "command")
# Set the menu item's icon
winreg.SetValueEx(menu_key, "Icon", 0, winreg.REG_SZ, icon_path)
# Create a new key for our menu item
winreg.SetValueEx(command_key, "", 0, winreg.REG_SZ, command)
# Close the keys
winreg.CloseKey(menu_key)
winreg.CloseKey(command_key)
winreg.CloseKey(key)
I have a simple python3.9 rumps app, roughly following the documented example https://rumps.readthedocs.io/en/latest/examples.html.
main.py:
import rumps
class SiMenuBarApp(rumps.App):
def __init__(self):
super(SiMenuBarApp, self).__init__("SiProdHacks")
self.menu = ["Item1"]
#rumps.clicked("Item1")
def item_one(self, _):
print("Hi Si!")
rumps.notification("SiProdHacks", "Keeping Si's Brain Free since 2021", "KAPOWIE!")
if __name__ == '__main__':
app = SiMenuBarApp()
app.icon = "happyicon.png"
app.run()
It runs fine, but when I click the menu bar item1, it prints my console message, but no notification occurs.
I am using python 3.9.0, rumps=0.3.0, iTerm and Mac OS 10.15.7 (Catalina).
Console output is:
❯ pipenv run python main.py
Hi Si!
Ok, I did some more digging on this, and discovered the debug mode of rumps:
import rumps
rumps.debug_mode(True)
which added the following to the output:
In this case there is no file at "/Users/simonrowland/.local/share/virtualenvs/si-menu-productivity-mlyLc7OG/bin/Info.plist"
Running the following command should fix the issue:
/usr/libexec/PlistBuddy -c 'Add :CFBundleIdentifier string "rumps"' /Users/simonrowland/.local/share/virtualenvs/si-menu-productivity-mlyLc7OG/bin/Info.plist
Running the suggested command:
/usr/libexec/PlistBuddy -c 'Add :CFBundleIdentifier string "rumps"' ${PATH_TO_VENV_BIN_DIR}/bin/Info.plist
Made it work!
I use following code to access hidden icon and to show its popup menu and to click on "Sign Off" menuitem:
import time
from pywinauto.application import Application
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(0.25)
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)
list_box_win.child_window(title="Citrix Workspace").click_input(button='right').menu_item('Sign Out').click_input()
Popup menu is shown, but I got error: AttributeError: 'NoneType' object has no attribute 'menu_item'
When I tried to add this code (instead of .menu_item('Sign Out').click_input()) :
connector = Application()
connector.connect(path="C:\\Program Files (x86)\\Citrix\\ICA Client\\SelfServicePlugin\\SelfService.exe")
connector.PopupMenu.MenuItem("Sign Out").ClickInput()
path is reflecting application that responsible for icon in system tray.
I got error: MatchError: Could not find 'PopupMenu' in 'dict_keys([])'. So I can I access menuitem in popup window?
BTW: It is run on windows 10 64 bit with python 3.6.
Unpolished/optimized (but working) code looks like this:
import pywinauto.application
import time
taskbar = pywinauto.application.Application(backend="uia").connect(path="explorer.exe")
windows_tray = taskbar.window(class_name="Shell_TrayWnd")
tray = windows_tray.child_window(title="Notification Chevron").wrapper_object()
tray.click()
time.sleep(1)
app_list_box = pywinauto.application.Application(backend="uia").connect(class_name="NotifyIconOverflowWindow")
app_list_box_win = app_list_box.window(class_name="NotifyIconOverflowWindow")
target_app = app_list_box_win.child_window(title = "Citrix Workspace")
target_app.click_input(button = "right")
citrix = pywinauto.application.Application().connect(path='Receiver.exe')
sign = citrix.PopupMenu.menu().get_menu_path("Sign In...")[0]
sign.click_input()
Where 'Receiver.exe' is executable of application running in system tray and "Citrix Workspace" title of of it.
I'm trying to get the Window ID of the SDL window, to give to VLC so it can play the video in the window.
Being new to Python, I'm vaguely aware this has to do with variable type conversions to play nice with SDL, and using the correct python binding...
The line with the error is "win_id = SDL_GetWindowID(window)"
Here is my code;
import sys
import sdl2.ext
import vlc
import ctypes
from sdl2 import *
RESOURCES = sdl2.ext.Resources(__file__, "resources")
sdl2.ext.init()
window = sdl2.ext.Window("Hello World!", size=(640, 480))
window.show()
factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE)
sprite = factory.from_image(RESOURCES.get_path("hello.bmp"))
spriterenderer = factory.create_sprite_render_system(window)
spriterenderer.render(sprite)
vlcInstance = vlc.Instance("--no-xlib")
player = vlcInstance.media_player_new()
win_id = SDL_GetWindowID(window)
player.set_xwindow(win_id)
player.set_mrl("agro.mp4")
player.play()
processor = sdl2.ext.TestEventProcessor()
processor.run(window)
sdl2.ext.quit()
What you get with SDL_GetWindowID is SDL's internal window ID that it itself refers to in e.g. events. What you need is X11 window ID, which you can get through SDL_GetWindowWMInfo. That however requires some trickery with SDL versioning, e.g. (I'm not sure it is safe to call that in python if SDL version changes but pysdl2 is not updated):
wminfo = SDL_SysWMinfo();
SDL_GetVersion(wminfo.version);
if(SDL_GetWindowWMInfo(window.window, wminfo) == 0):
print("can't get SDL WM info");
sys.exit(1);
win_id = wminfo.info.x11.window;
Then use that win_id to feed to vlc.
I am new to PyQt, I am developing an application like MDI, I use the QDesigner to build the forms (I come from Visual Basic), so far so good, but it is costing me horrors to run the application well, when I close a window, erase everything, but the frame remains on the mdi-area, click on the x and close. I attach the code.
With this I knock at the window:
def ordentrabajo(self):
self.cot = FichaOrdenTrabajo()
subwindow = QtGui.QMdiSubWindow()
self.cot.mdiarea = self.ventana.mdiArea
subwindow.setWidget(self.cot)
subwindow.setGeometry(0, 0, 595, 490)
self.ventana.mdiArea.addSubWindow(subwindow)
subwindow.showventana = self.cot.show()
And within the FichaOrdenTrabajo I close with:
def closeEvent(self, QCloseEvent):
self.emit(QtCore.SIGNAL('cerrar'))
general.saveposic('ctrlordentrabajo', self.x(), self.y())
self.subwindow.close = self.cdeta.close()
self.cdeta.hide()
# del self.subwindow
self.subwindow = None
leaving the main window in this state:
The question is how to do so that when closing the mdi-area is clean?
Thank you