Setting Application Menu name in GTK+/Python (fixing "Unknown Application Name") - python

When running GTK+ apps under Ubuntu 12.04, how do you set the application name that is displayed in the Application-level menu?
Here's an example app:
from gi.repository import GLib, Gtk, Gio
import sys
class MyApp(object):
def __init__(self):
GLib.set_application_name('My App')
self.app = Gtk.Application.new('org.example.test', 0)
self.app.connect('startup', self.on_app_startup)
self.app.connect('activate', self.on_app_activate)
self.app.connect('shutdown', self.on_app_shutdown)
def run(self, argv):
self.app.run(argv)
def on_app_startup(self, app):
self.window = Gtk.ApplicationWindow.new(app)
self.window.set_default_size(640, 480)
self.window.set_title('AppMenu Demo')
app.add_window(self.window)
# # App menu
app_menu = Gio.Menu()
section = Gio.Menu()
item = Gio.MenuItem.new('Quit', 'app.quit')
item.set_attribute_value("accel", GLib.Variant("s", "<Control>Q"))
section.append_item(item)
app_menu.append_section(None, section)
app.set_app_menu(app_menu)
# # Menu bar
menu_bar = Gio.Menu()
submenu = Gio.Menu()
section = Gio.Menu()
section.append_item(Gio.MenuItem.new('Help', 'app.help'))
submenu.append_section(None, section)
menu_bar.append_submenu('Help', submenu)
app.set_menubar(menu_bar)
action = Gio.SimpleAction.new('quit', None)
action.connect('activate', self.on_quit)
app.add_action(action)
def on_app_activate(self, app):
self.window.show_all()
def on_app_shutdown(self, app):
pass
def on_quit(self, action, data=None):
self.app.quit()
if __name__ == '__main__':
app = MyApp()
app.run(sys.argv)
If you run this code under Ubuntu 12.04, it pops up a window labeled "AppMenu Demo"; the control bar at the top of the screen shows this name as well. If you move your mouse to the control bar, two pulldown menus are displayed; the app menu, and a "Help" menu.
This is all fine - except that the name of the Application menu is "Unknown Application Name". I can't find any way to alter this name. GLib.set_application_name(name) doesn't do it. How do you set the application name?
Or: is this a case where GTK+ is ahead of what Ubuntu supports? Google searches for "unknown application name" point at a range of bug reports and merged patches, which suggests to me that this might be an area of current development, rather than stable API. A quick survey of apps installed in Ubuntu shows that most apps have a "File" menu, but nothing that would be identified as an "app" menu of the type that GTK+ seems to support. Should I just abandon app menus until they're better supported at an OS level?

It is a ubuntu specific/unity specific/ancient gtk+ 3.4.x/gtk+ 3.6.x bug.
With somewhat current (gtk+ 3.10.7 and Cinnamon 2.014 as DE) it works just fine.

Related

Context menu trigger intermittent on Mac OS X

I'm using right mouse clicks to display a context-sensitive menu within a QTreeView-based GUI. The context menu works correctly on Windows and Ubuntu. On Mac OS X, the context menu displays correctly but when the user selects an option from the context menu the corresponding operation is only performed about once every 10 times the menu is invoked and a selection made.
The environment is Python V3.9.6 and PyQt V5.12.3 on all machines, installed using conda. The Ubuntu machine is 20.04, Windows 10 is a virtual machine (VBox) under the Ubuntu host and the Mac OS X machine is a MacInCloud server running Catalina.
I've included an MRE below that puts up a basic tree view. Right clicking on an entry will display the context menu and selecting a context menu entry should print a message in the console. This works correctly on Ubuntu and Windows but only intermittently on Mac OS X.
import sys
from PyQt5 import QtGui
from PyQt5 import QtWidgets
from PyQt5 import QtCore
class main_ui(QtWidgets.QWidget):
def __init__(self):
super(main_ui, self).__init__()
# set the window title and size
self.setWindowTitle("Context menu trigger")
self.resize(500, 300)
# set the model
self.model = QtGui.QStandardItemModel()
self.model.setHorizontalHeaderLabels(["Variable"])
# set the view and link it to the model
self.view = QtWidgets.QTreeView()
self.view.setModel(self.model)
self.view.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.view.customContextMenuRequested.connect(self.context_menu)
self.view.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectItems)
# define the context menu
self.context_menu = QtWidgets.QMenu()
self.context_menu.plot_time_series = QtWidgets.QAction(self)
self.context_menu.plot_time_series.setText("Plot time series")
self.context_menu.plot_time_series.triggered.connect(self.plot_time_series)
self.context_menu.addAction(self.context_menu.plot_time_series)
# create the model
self.create_model()
# set the layout
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.view)
def context_menu(self, position):
print("Displaying context menu")
self.context_menu.exec_(self.view.viewport().mapToGlobal(position))
def create_model(self):
keys = ["Variable1", "Variable2", "Variable3"]
for key in keys:
self.model.appendRow([QtGui.QStandardItem(key)])
def plot_time_series(self):
print("In plot_time_series")
if (__name__ == '__main__'):
app = QtWidgets.QApplication(["Test"])
ui = main_ui()
ui.show()
sys.exit(app.exec_())
I have tried reverting to earlier versions of Python 3 and PyQt but the problem persists and I've been unable to find a related question here or elsewhere.
Further debugging of this problem showed that the intermittent behaviour of the right-click context menu only occurred on a "cloud-based" Mac running Catalina. The problem did not occur on a "cloud-based" Mac running High Sierra or on a physical Mac running Catalina.

UI made in QT Designer shifts behind Title Bar [duplicate]

I'm trying to create an application that contains a web browser within it, but when I add the web browser my menu bar visually disappears but functionally remains in place. The following are two images, one showing the "self.centralWidget(self.web_widget)" commented out, and the other allows that line to run. If you run the example code, you will also see that while visually the entire web page appears as if the menu bar wasn't present, you have to click slightly below each entry field and button in order to activate it, behaving as if the menu bar was in fact present.
Web Widget Commented Out
Web Widget Active
Example Code
import os
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtWebEngineWidgets import *
class WebPage(QWebEngineView):
def __init__(self, parent=None):
QWebEngineView.__init__(self)
self.current_url = ''
self.load(QUrl("https://facebook.com"))
self.loadFinished.connect(self._on_load_finished)
def _on_load_finished(self):
print("Url Loaded")
class MainWindow(QMainWindow):
def __init__(self, parent=None):
# Initialize the Main Window
super(MainWindow, self).__init__(parent)
self.create_menu()
self.add_web_widet()
self.show()
def create_menu(self):
''' Creates the Main Menu '''
self.main_menu = self.menuBar()
self.main_menu_actions = {}
self.file_menu = self.main_menu.addMenu("Example File Menu")
self.file_menu.addAction(QAction("Testing Testing", self))
def add_web_widet(self):
self.web_widget = WebPage(self)
self.setCentralWidget(self.web_widget)
if __name__ == "__main__":
app = QApplication(sys.argv)
main_window = MainWindow()
main_window.showMaximized()
sys.exit(app.exec_()) # only need one app, one running event loop
Development Environment
Windows 10, PyQt5, pyqt5-5.9
EDIT
The problem doesn't seem to be directly related to the menu bar. Even removing the menu bar the issue still occurs. That said, changing from showMaximized() to showFullScreen() does seem to solve the problem.
I no longer believe this is an issue with PyQt5 specifically but rather a problem with the graphics driver. Specifically, if you look at Atlassian's HipChat application it has a similar problem which is documented here:
https://jira.atlassian.com/browse/HCPUB-3177
Some individuals were able to solve the problem by running the application from the command prompt with the addendum "--disable-gpu" but that didn't work for my python application. On the other hand, rolling back the Intel(R) HD Graphics Driver did solve my problem. Version 21.20.16.4627 is the one that seems to be causing problems.

Python : Add url to menu in appindicator

I'm trying to make a little application with appindicator and Gtk. My goal is to display a list of server with link to url of them.
Here is what I try :
from gi.repository import Gtk as gtk
from gi.repository import AppIndicator3 as appindicator
def main():
indicator = appindicator.Indicator.new(APPINDICATOR_ID, img, appindicator.IndicatorCategory.SYSTEM_SERVICES)
indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
indicator.set_menu(build_menu())
gtk.main()
def build_menu():
menu = gtk.Menu()
value = "label"
item = gtk.MenuItem()
button = gtk.LinkButton("http://url/host/id", label=value)
button.show()
item.add(button)
item.show()
menu.append(item)
menu.show_all()
return menu
if __name__ == "__main__":
main()
That's working and I have no errors. But wen I launch application, I've only menu, with items but no link.
I've seen many exemple with gtk.Window but nothing with a menu for appindicator.
Is there a way to have link in this menu ?
Thanks
I've found a way to do that. I'm not sure it's the best way, but it works.
Instead of create a LinkItem, I've made a function for open url:
def open_url(source):
webbrowser.open("http://url/host/id")
And I call it after, with connect :
item.connect("activate", open_url)
When I run my app and click on my item, it opens url as expected. Here is part of code working:
def build_menu():
menu = gtk.Menu()
value = "label"
item = gtk.MenuItem(value)
item.connect("activate", open_url)
menu.append(item)
menu.show_all()
return menu
As I see in many post on web, appindicator has limited functions compared to normal Gtk application.

Update menu in QT system tray application

I need to update the existing menu items for a system tray application. At first when the app loads, there will be two menu items. Later when I click a button these menu items need to be replaced with new menu items. How can I achieve that ? Here is my code.
from PySide.QtGui import *
import sys
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.tray = QSystemTrayIcon(QApplication.style().standardIcon(QStyle.SP_DriveDVDIcon), self)
self.m = QMenu()
self.m.addAction('First')
self.m.addAction('Second')
self.tray.setContextMenu(self.m)
self.tray.show()
p = QPushButton("Click Me", self)
self.setCentralWidget(p)
p.clicked.connect(self.onClick)
def onClick(self):
self.m.clear()
self.m.addAction('First')
self.m.addAction('Third')
self.tray.setContextMenu(self.m)
app = QApplication(sys.argv)
w = MainWindow()
w.show();
sys.exit(app.exec_())
However this is not working. If I try removing self.m.clear()the new menu items will append to the existing (Which is the normal behaviour in this case). Isn't menu.clear() clears the current menu & the new menu should be populated here ?
I have seen this similar question Qt QSystemTrayIcon change menu items and the solution doesn't work for me. I am running Ubuntu 14.04.
I figured it out, the problem is due to the self.tray.setContextMenu(self.m). Remove this line from onClick method. This should work fine on Ubuntu.

Detect scroll wheel signal in system tray using Python AppIndicator in Ubuntu 12.04

I'm trying to get this python code to react when the mouse hovers over the tray icon and scrolls the mouse wheel, I can't find any examples online. This is what I have so far, it doesn't react to scrolling the wheel...
#!/usr/bin/python
APPNAME = "My App"
ICON = "/usr/share/pixmaps/firefox.png"
import appindicator as AI
import gtk
def sayhello(item):
print "menu item selected"
def scroll(aai, ind, steps):
print "hello" # doesn't print anything
def makemenu():
' Set up the menu '
menu = gtk.Menu()
check = gtk.MenuItem('Check')
exit = gtk.MenuItem('Quit')
check.connect('activate', sayhello)
exit.connect('activate', gtk.main_quit)
menu.append(check)
menu.append(exit)
return menu
def startapp():
ai = AI.Indicator(APPNAME, ICON, AI.CATEGORY_APPLICATION_STATUS)
ai.set_status(AI.STATUS_ACTIVE)
ai.connect("scroll-event", scroll)
ai.set_menu(makemenu())
gtk.main()
startapp()
How can I detect scroll wheel movements?
That is the correct way to connect to the mouse scroll event and the code does work, tested on two 12.04 systems. There might be a bug however as the first few test runs on one of them did not work either but then was fine.
If you are starting from scratch I would recommend using pygobject (Gtk3) instead of pygtk (Gtk2) as it is no longer developed. As part of testing I did convert your script to pygobject and fixed showing the menu:
#!/usr/bin/env python
APPNAME = "My App"
ICON = "/usr/share/pixmaps/firefox.png"
from gi.repository import AppIndicator3 as AI
from gi.repository import Gtk
def sayhello(item):
print "menu item selected"
def scroll(aai, ind, steps):
print "hello" # doesn't print anything
def makemenu():
' Set up the menu '
menu = Gtk.Menu()
check_item = Gtk.MenuItem('Check')
exit_item = Gtk.MenuItem('Quit')
check_item.connect('activate', sayhello)
check_item.show()
exit_item.connect('activate', Gtk.main_quit)
exit_item.show()
menu.append(check_item)
menu.append(exit_item)
menu.show()
return menu
def startapp():
ai = AI.Indicator.new(APPNAME, ICON, AI.IndicatorCategory.HARDWARE)
ai.set_status(AI.IndicatorStatus.ACTIVE)
ai.set_menu(makemenu())
ai.connect("scroll-event", scroll)
Gtk.main()
startapp()

Categories