Pyside: Updating icons when changing the themeSearchPaths() - python

I'm currently trying to enable switching the icon theme of an application during runtime.
The problem is that I just cant figure out how to trigger the objects to "refresh" their icons and pick them from the new QIcon.themeSearchPaths().
def change_icon(self):
style = QApplication.style()
if self.standart_icon_theme_active:
QIcon.setThemeSearchPaths([""]) # resetting to the 'default' folder
QIcon.setThemeName(u"")
else:
QIcon.setThemeSearchPaths(["icons/"]) # the folder with my icons
QIcon.setThemeName(u"icons")
for btn in self.bttns:
btn.setIcon(style.standardIcon(getattr(QStyle, btn.objectName()))) # <= im searching for a signal or something to replace this
self.standart_icon_theme_active = not self.standart_icon_theme_active
What I currently have is a little demo Window with a lot of buttons, (which got created with a list of names of icons, so that their name equals the icon they have) in which each icon of each button gets updated when change_icon() gets triggered, and i'm searching for something like a builtin signal which I can emit to let Pyside update each icon on its own, or something in that way.
Any help would be appreciated.

Related

How to set QMenu tear-off window title?

I'm creating a custom ui in Maya 2017 which uses PyQt5 (well... technically PySide2, but it's essentially the same).
I've got a few CustomContextMenu popup menus that I've created in my ui and I've used popup.setTearOffEnabled(True) to be able to tear them off into a separate window (popup, being the QMenu item).
I cannot seem to figure out how to set the title for the resulting torn off window. Currently, each torn off window is titled "Maya-2017", but I'd like to give it a unique name for clarity. I've noticed that Maya's menu items with tear off functionality name the resulting window with the menu's name, so it would seem this is doable. Am I just missing something obvious?
I have tried using popup.setTitle('test name') on the QMenu thinking it would then name the tear off window this title, but it doesn't seem to do anything. Other than that, I'm at a loss.
I'm not sure whether torn-off menus appear the same on all platforms, but on my Linux system, they are shown as tool windows with a title-bar. So the title can be set like this:
menu = QMenu('File')
menu.setTearOffEnabled(True)
menu.setWindowTitle('File')

Implementing Gedit style fullscreen HeaderBar

I am working on a Gtk+ 3 application that is likely to be used fullscreen most of the time, but needs to be switched between fullscreen and non-fullscreen, while maintaining access to the controls located in the header bar. The problem is, since the headerbar is part of the window decorations, it gets hidden when the window goes fullscreen.
My current kludge so ensure the controls are always available works like this:
Setup
create a Gtk.Window with vertical Gtk.Box as first child
create a custom Gtk.HeaderBar (w/ added full screen togglebutton)
set window's titlebar as my custom Gtk.HeaderBar
add all the window's content to the Gtk.Box
When window goes fullscreen
remove the Gtk.HeaderBar from the Gtk.Window titlebar
pack the Gtk.HeaderBar into the Gtk.Box (window's first child).
This results in the Gtk.HeaderBar being at the bottom of the window, so
re-position the Gtk.HeaderBar to the top of the Gtk.Box
When the window goes un-fullscreen
remove the Gtk.HeaderBar from the gtk.Box
set it as the Gtk.Window's titlebar
This results in the following Gtk-warning: gtk_window_set_titlebar() called on a realized window (who cares, just a warning)
This works, but it seems like very much of a hack, and more complicated than it should have to be. Am I missing something and there is a more straightforward approach?
I know several Gtk+ 3 based apps have the header bar behavior I am after (gedit for example), but I have not been able to determine how that is implemented. Any insight would be greatly appreciated.
Also, here is a GitHub gist with a full working example of my current hacky solution: https://gist.github.com/KurtJacobson/6b045b6fc38907a2f18c38f6de2929e3
I will accept answers in any (programming) language.

How do I manage a dynamic, changing main menu in wxPython?

I'm writing a document based application in wxPython, by which I mean that the user can have open multiple documents at once in multiple windows or tabs. There are multiple kinds of documents, and the documents can all be in different "states", meaning that there should be different menu options available in the main menu.
I know how to disable and enable menu items using the wx.EVT_UPDATE_UI event, but I can't figure out how to pull off a main menu that changes structure and content drastically based on which document that currently has focus. One of my main issues is that the main menu is created in the top level window, and it has to invoke methods in grand children and great grand children that haven't even been created yet.
Contrived example; when a document of type "JPEG" is open, the main menu should look like:
File Edit Compression Help
And when the user switches focus (CTRL+Tab) to a document of type "PDF", the main menu should change to:
File Edit PDF Publish Help
And the "Edit" menu should contain some different options from when the "JPEG" document was in focus.
Current I'm just creating the menu in a function called create_main_menu in the top level window, and the document panels have no control over it. What would be necessary to pull off the kind of main menu scheme I describe above, specifically in wxPython?
I've figured out a pretty clean way to do this. First of all I create my "base" main menu bar, which contains the File and Help menu items. Then I defined a class EditorPanel than is a subclass of wx.Panel and defined the methods bind_main_menu_bar and release_main_menu_bar. The first of those methods receives the main menu bar when the panel is focused, and adds some items to it. Here is one of my implementations:
def bind_main_menu_bar(self, main_menu_bar):
main_frame = wx.GetApp().GetTopWindow()
self.main_menu_bar = main_menu_bar
# Create the edit menu.
self.edit_menu = edit_menu = shared.create_menu([
(const.ID_UNDO, self.LABEL_UNDO_EMPTY),
(const.ID_REDO, self.LABEL_REDO_EMPTY)
])
# Create the tools menu.
self.tools_menu = tools_menu = shared.create_menu([
(const.ID_SELECT_ADDRESS_COLUMNS, 'Select address columns...'),
(),
(const.ID_VALIDATE_ADDRESSES, 'Validate selected addresses'),
(const.ID_VALIDATE_ALL_ADDRESSES, 'Validate all addresses')
])
# Bind some menu event handlers to the main frame.
main_frame.Bind(wx.EVT_MENU, self.on_menu)
main_frame.Bind(wx.EVT_UPDATE_UI, self.on_menu_update)
# Insert the new menus into the main menu bar.
main_menu_bar.Insert(1, edit_menu, 'Edit')
main_menu_bar.Insert(2, tools_menu, 'Tools')
Now, when that editor panel is opened, the main menu receives an Edit menu and a Tools menu that is bound to event handlers in the EditorPanel, which is incredibly handy. When the editor loses focus, the release_main_menu_bar method is called, which should restore the main menu bar to it's original state. This is counterpart of the code above:
def release_main_menu_bar(self):
main_frame = wx.GetApp().GetTopWindow()
# Unbind the menu event handlers from the main frame.
main_frame.Unbind(wx.EVT_MENU, handler=self.on_menu)
main_frame.Unbind(wx.EVT_UPDATE_UI, handler=self.on_menu_update)
# Remove the edit and tools menu from the main menu bar.
self.main_menu_bar.Remove(1)
self.main_menu_bar.Remove(1)
# Reset the fields used for the menu.
self.edit_menu = None
self.tools_menu = None
self.main_menu_bar = None
So every editor that wants to edit the main menu just has to subclass those two methods and they have full control. The main frame will monitor when the user switches between editors and call the methods accordingly. The biggest problem was to figure out when the editor panel receives and loses focus, which is the topic of another question of mine: How do I monitor when wx.Panel receives and loses focus?
Probably the only way to do it with the standard wx.Menu is to destroy and recreate the entire menubar. You might be able to Hide it though. Either way, I think it would be easiest to just put together a set of methods that creates each menubar on demand. Then you can destroy one and create the other.
You might also take a look at FlatMenu since it is pure Python and easier to hack.

custom libindicator icon is not displayed

I want to change the status icon of my own little reminder program. Currently I am using GTK.StatusIcon but I want to use a ApplicationIndicator.
Therefore I created an own Icon and moved it to:
/usr/share/icons/ubuntu-mono-dark/status/22
It is named indicator-notify.svg
Heres the code for the icon.
ind = appindicator.Indicator ("notify",
"indicator-notify",
appindicator.CATEGORY_APPLICATION_STATUS)
ind.set_status (appindicator.STATUS_ACTIVE)
This Icon is not displayed. Although every other icon from this folder is.
What did I miss? Is there maybe the need to "register" the icon in GTK ?
You don't need to register it, but your icon cache needs to be updated after installing new icons. You can do this via gtk-update-icon-cache (see http://developer.gnome.org/gtk/2.24/gtk-update-icon-cache.html)

How I can add a Widget or a Region to an Status Icon in PyGTK

This is my first question in StackOverflow, so I would try to explain my self the best I can.
I made an small app trying to emularte the windows Procastination Killer Application, using pygtk and pygame for the sound alerts.
Here is a video of my little app running http://www.youtube.com/watch?v=FmE-QPA9p-8
My Issue is that I want to get a widget in the tray icon area, and not jus the plain Icon. Something like an Icon and a Label, to made a counter, or at least extend the icon size to put more information in the status icon.
So my Questions would be:
How can I resize the status icon? for example to show a icon 44x22 pixels
How can I add a Widget, Region, or something else instead the status icon
Here is the code that use to get the status icon.
self.status_icon = gtk.StatusIcon()
self.status_icon.set_from_file(STATUS_ICON_FILE)
self.status_icon.set_tooltip("Switch, a procastination killer app")
self.status_icon.connect("activate", self.on_toggle_status_trayicon)
self.status_icon.connect("popup-menu", lambda i, b, a: self.status_menu.popup(
None, None, gtk.status_icon_position_menu, b, a, self.status_icon))
I am packaging the app for ubuntu soon as I find a name :), that maybe would be me third question.
3: How do I name my app?
GTK+ doesn't support arbitrary widgets in the notification area, because these don't work well in Windows. You probably want to write a panel applet instead -- here's a tutorial for panel applets in PyGTK.

Categories

Resources