I want to show simple popup menu with right click, menu works right but menu separators are missing, I searched similar examples but they all using pygtk but I'm using gi.repository I don't know is my code wrong or this problem is all about libraries.
my code is
#!/usr/bin/python
from gi.repository import Gtk
class Win(Gtk.Window):
def __init__(self):
super(Win, self).__init__()
self.resize(400,280)
self.button = Gtk.Button()
self.add(self.button)
self.button.connect("button-press-event", self.button_press)
self.connect("destroy", Gtk.main_quit)
self.show_all()
def button_press(self,widget,event):
if event.button == 3:
self.menu = Gtk.Menu()
self.menu_copy = Gtk.MenuItem("Copy")
self.menu_paste = Gtk.MenuItem("Paste")
self.menu_select_all = Gtk.MenuItem("Select All")
self.menu.append(self.menu_copy)
self.menu.append(self.menu_paste)
# separator 1
self.menu.append(Gtk.SeparatorMenuItem())
# separator 2
self.menu.append(Gtk.MenuItem())
self.menu.append(self.menu_select_all)
self.menu.show_all()
self.menu.popup(None, None, None, None, event.button, event.get_time())
pass
def main():
app = Win()
Gtk.main()
if __name__ == "__main__":
main()
and here is the screenshot of my menu Example 1
What version of pygobject do you have? I submitted a patch for that back in June and it was fixed in 3.3.4: https://bugzilla.gnome.org/show_bug.cgi?id=670575
If the separator works properly when you use Gtk.SeparatorMenuItem.new() instead of the constructor than you know it's the aforementioned bug.
Related
I'm pretty new to OOP and gtk programming, so sorry if the answer my question is really obvious, but I can't find a solution. I am trying to make a browser-like interface using the Gtk notebook. I wrote a method to add tabs, and it seems to work, becasue when I call it in the init, it works, and adds a new tab. Here the method is:
def create_page(self, button):
print("creating a new page")
print(self)
self.newpage = Gtk.Box()
self.newpage.set_border_width(50)
self.newpage.add(Gtk.Label.new("add notes here"))
self.notebook.append_page(self.newpage, Gtk.Label.new("new page"))
The reason the method has to have the button parameter is becasue I want it to be called by a button, and for that to happen, it has to have a button parameter.
When the button calls the parameter, the print statment works, and it prints its self <main.MyWindow object at 0x7efd64e52a80 (main+MyWindow at 0xe60270)>. It prints the exact same output as when I call it from the init.The problem is that it never actually adds the new notebook tab for some reason. Here my full code is:
import gi
# Since a system can have multiple versions
# of GTK + installed, we want to make
# sure that we are importing GTK + 3.
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title ="Stickies Hub")
#self.set_border_width(70)
# Create Notebook
self.notebook = Gtk.Notebook.new()
self.add(self.notebook)
#create buttons
self.new_tab = Gtk.Button(label=("button"))
self.new_tab.connect("clicked", self.create_page)
# Create pages
self.page1 = Gtk.Box()
self.page1.set_border_width(50)
self.page1.add(Gtk.Label.new("Welcome to Geeks for Geeks"))
self.notebook.append_page(self.page1, Gtk.Label.new("Click Here"))
self.page2 = Gtk.Box()
self.page2.set_border_width(50)
self.page2.add(Gtk.Label.new("A computer science portal for geeks"))
self.page2.add(self.new_tab)
self.notebook.append_page(self.page2, Gtk.Label.new("Click Here"))
self.create_page(self.new_tab)
self.create_page(self.new_tab)
def create_page(self, button):
print("creating a new page")
print(self)
self.newpage = Gtk.Box()
self.newpage.set_border_width(50)
self.newpage.add(Gtk.Label.new("new page"))
self.notebook.append_page(self.newpage, Gtk.Label.new("new page"))
win = MyWindow()
win.connect("destroy", Gtk.main_quit)
# Display the window.
win.show_all()
# Start the GTK + processing loop
Gtk.main()
How can I add a new notebook tab from a button?
Thanks so much for help!
As jackw11111 said, the solution was to add self.show_all() at the end of create_page function. Thanks so much!
I made an answer so anyone with this same problem could easily find the answer.
Helloo, Here is my code. I think this will work for you.
from gi.repository import Gdk
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class MyWindow(Gtk.Window):
notebook = Gtk.Notebook()
def __init__(self):
Gtk.Window.__init__(self)
self.set_default_size(750, 500)
self.connect("destroy", Gtk.main_quit)
self.list_view()
def list_view(self):
self.table = Gtk.Table(n_rows=3, n_columns=3, homogeneous=True)
listbox = Gtk.ListBox()
self.add(self.table)
self.add(listbox)
self.two_d_array = {'Hello' : 'Hi', 'Example' : 'Merhaba'}
for i in self.two_d_array.keys():
## label yerine buton oluşturduk
items = Gtk.Button.new_with_label(i)
items.connect("button-press-event",self.button_clicked)
listbox.add(items)
self.table.attach(listbox,0,1,0,3)
self.add(self.notebook)
self.table.attach(self.notebook,1,3,0,3)
self.notebook.show_all()
self.page1 = Gtk.Box()
self.page1.set_border_width(10)
self.page1.add(Gtk.Label(label="Merhaba bu ilk sayfa."))
self.notebook.append_page(self.page1, Gtk.Label(label="Default Page"))
def context_menu(self):
menu = Gtk.Menu()
menu_item = Gtk.MenuItem("New Page")
menu.append(menu_item)
menu_item.connect("activate", self.on_click_popup)
menu.show_all()
return menu
## Buton sağ click ise context menu açtı
def button_clicked(self,listbox_widget,event):
if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
menu = self.context_menu()
## Tıklanan objenin labelini print ediyor
print(listbox_widget.get_label())
self.labelmenu = listbox_widget.get_label()
menu.popup( None, None, None,None, event.button, event.get_time())
return True
def on_pop_menu(self, widget, event):
if event.button == 3:
widget.popup(None, None, None, None, event.button, event.time)
def on_click_popup(self, action):
## Yeni sayfa oluştur
self.new_page = Gtk.Box()
self.new_page.set_border_width(10)
self.new_page.add(Gtk.Label(label=self.two_d_array[self.labelmenu]))
self.notebook.append_page(self.new_page, Gtk.Label(label="New Page"))
self.close_button = Gtk.Button()
self.close_button.set_image(Gtk.Image(Gtk.STOCK_CLOSE,Gtk.IconSize))
self.close_button.connect('clicked')
self.close_button.show()
self.notebook.show_all()
window = MyWindow()
window.show_all()
Gtk.main()
Please see this code example:
import gtk
class MenuBox(gtk.EventBox):
def __init__(self):
super(MenuBox, self).__init__()
self.set_visible_window(False)
self.connect('enter-notify-event', self._on_mouse_enter)
self.connect('leave-notify-event', self._on_mouse_leave)
btn = gtk.Button('x')
btn.set_border_width(12)
self.add(btn)
def _on_mouse_enter(self, wid, event):
print '_on_mouse_enter'
def _on_mouse_leave(self, *args):
print '_on_mouse_leave'
def main():
win = gtk.Window()
win.connect('destroy', gtk.main_quit)
win.add(MenuBox())
win.show_all()
gtk.main()
if __name__ == '__main__':
main()
I want that the enter and leave events are not triggered if I am going from parent to child and back. I know that in this particular case I can filter these events with event.detail. But this does not work if there is no border. If I remove the border the events aren't triggered at all.
In my real code I have a more complex widget (based on gtk.Fixed) which has border at the beginning but not at the end. So just moving the event to the child wouldn't do the trick either.
# self.set_visible_window(False)
self.connect('enter-notify-event', self._on_mouse_enter)
self.connect('leave-notify-event', self._on_mouse_leave)
btn = gtk.Button('x')
# btn.set_border_width(12)
Is that what you need?
This is an example of code for simple system tray PyQt application.
import sys
from PyQt4 import QtGui
def main():
app = QtGui.QApplication(sys.argv)
trayIcon = QtGui.QSystemTrayIcon(QtGui.QIcon('test.png'), app)
menu = QtGui.QMenu()
exitAction = menu.addAction("Exit")
trayIcon.setContextMenu(menu)
# I'd like to show picture in tooltip, BUT IT'S NOT WORK IN WINDOWS
trayIcon.setTooltip('<img src="SomePicture.png" width="48" height="48"/>')
trayIcon.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
In this code I'd like to show balloon tooltip with a some picture and some kind of text formating. For this purpose I use RichText tags formatting. As the result for Ubuntu Linux system (Gnome desktop) everything is Ok. But when I try use RichText formatting for tooltip in Windows XP system, nothing works. Tooltip text equals source string: ''.
Python version on Windows 2.7, on Linux 2.6 but I think that problem is not in different versions.
If in Windows OS RichText isn't parsing how can I make same kind of GUI (Crossplatform is prefered)?
On Windows Qt uses the os' tooltip system, which only supports text.
If you want something more advanced, you could QSystemTrayIcon.showMessage() use as described here. You'll probably have to install an eventfilter or override the QTrayIcons event method to get the help event.
If someone also interested in create of balloon widget. This my code:
class SystemTrayIcon(QtGui.QSystemTrayIcon):
def __init__(self, parent = None):
QtGui.QSystemTrayIcon.__init__(self, icon, parent)
traySignal = "activated(QSystemTrayIcon::ActivationReason)"
self.connect(self, QtCore.SIGNAL(traySignal), self._activateRoutine)
self.balloon = balloonWidget(name)
def _activateRoutine(self, reason):
if reason == QtGui.QSystemTrayIcon.Trigger:
self.balloon.show(self.geometry())
class balloonWidget(QtGui.QWidget):
def __init__(self,name):
QtGui.QWidget.__init__(self, parent = None, flags = QtCore.Qt.Popup)
self.name = name
self.offsetX = 10
self.offsetY = 10
self.outInfo = QtGui.QLabel(self)
self.setStyleSheet("QWidget {border:5px solid rgb(170, 170, 255);}")
def show(self,coord):
richText = tr('Any text with Rich Format')
self.outInfo.setText(richText)
self.outInfo.show()
self.adjustSize()
origin = QtGui.QDesktopWidget().availableGeometry().bottomRight()
if coord.y() < origin.y()/2:
moveY = coord.bottomLeft().y() + self.offsetY
else:
moveY = coord.topLeft().y() - (self.height() + self.offsetY)
if coord.x() + self.width() + self.offsetX >= origin.x():
moveX = origin.x() - (self.width() + self.offsetX)
else:
moveX = coord.x()
self.move(moveX,moveY)
self.setVisible(True)
def closeEvent(self, event):
event.ignore()
self.hide()
def mousePressEvent(self, event):
self.close()
How could I have a scrollbar inside a gtk.Layout.
For example, in my code I have:
import pygtk
pygtk.require('2.0')
import gtk
class ScrolledWindowExample:
def __init__(self):
self.window = gtk.Dialog()
self.window.connect("destroy", self.destroy)
self.window.set_size_request(300, 300)
self.scrolled_window = gtk.ScrolledWindow()
self.scrolled_window.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
self.window.vbox.pack_start(self.scrolled_window, True, True, 0)
self.layout = gtk.Layout()
self.scrolled_window.add(self.layout)
self.current_pos = 0
self.add_buttom()
self.window.show_all()
def add_buttom(self, widget = None):
title = str(self.current_pos)
button = gtk.ToggleButton(title)
button.connect_object("clicked", self.add_buttom, None)
self.layout.put(button, self.current_pos, self.current_pos)
button.show()
self.current_pos += 20
def destroy(self, widget):
gtk.main_quit()
if __name__ == "__main__":
ScrolledWindowExample()
gtk.main()
What I really want is to find some way to make the scroll dynamic. See the example that I put above, when you click any button, another button will be added. But the scrollbar doesn't work.
What can I do to get the scroll bars working?
Does it works if you either use gtk.Window() instead of gtk.Dialog(); or execute self.window.run() after self.window.show_all()?
The difference between Dialog and common Window is that Dialog has its own loop which processes events. As you do not run its run() command, this loop never gets the chance to catch the events, so ScrolledWindow does not receives them, and does not change its size.
consider the following python code:
import gtk
class MainWindow():
def __init__(self):
self.window = gtk.Window()
self.window.show()
if __name__ == "__main__":
main = MainWindow()
gtk.main()
I'd need to catch clicks anywhere inside this gtk.Window().
I haven't found any suitable event (I also tried button-press-event, but it doesn't work), what am I missing?
Thank you!
You can pack a gtk.EventBox into the window. In general, whenever you have troubles catching events, check if gtk.EventBox solves them.
import gtk
class MainWindow():
def __init__(self):
self.window = gtk.Window()
self.box = gtk.EventBox ()
self.window.add (self.box)
self.box.add (gtk.Label ('some text'))
self.window.show_all()
import sys
self.box.connect ('button-press-event',
lambda widget, event:
sys.stdout.write ('%s // %s\n' % (widget, event)))
if __name__ == "__main__":
main = MainWindow()
gtk.main()
Note, however, that event propagation upwards the widget hierarchy will stop if a widget handles event itself. For instance, a parent of gtk.Button won't receive click events from it.
So i have this DrawingArea in Window. And on click i get the callback
self.drawingarea = gtk.DrawingArea()
self.drawingarea.connect ('button-press-event',self.callback)
self.drawingarea.set_events(gtk.gdk.EXPOSURE_MASK
| gtk.gdk.LEAVE_NOTIFY_MASK
| gtk.gdk.BUTTON_PRESS_MASK
| gtk.gdk.POINTER_MOTION_MASK
| gtk.gdk.POINTER_MOTION_HINT_MASK )
self.window.add(self.drawingarea)
Filter the left or right button:
def callback(self, widget, event):
print "clicking... left or right"
if event.button == 1:
print 'OK - clicked left '
#os.system("""wmctrl -s 0""")
return True