How do I use keyboard shortcuts with Gtk StackSwitcher? - python

What I want to do is make a shortcut keyboard key to switch between Page 1 and Page 2. For instance, pressing Ctrl+S would take me to Page 1 if I am not already there and likewise pressing Ctrl+R would take me to Page 2. I searched the documentation but I couldn't find anything related to what I need. Is there a way to implement it? Please see the below image:
Stack Switcher
Here's the snippet:
class App(Gtk.Application):
def __init__(self, *args, **kwargs):
super(App, self).__init__(*args, **kwargs)
self.connect('activate', self.on_activate)
self.send_stack = None
self.receive_stack = None
self.send_receive_stack = None
self.header_button_handler_id = None
self.pre_sign_widget = None
def on_activate(self, app):
ui_file_path = os.path.join(
os.path.dirname(os.path.abspath(__file__)),
"app.ui")
appwindow = 'applicationwindow1'
builder = Gtk.Builder()
builder.add_objects_from_file(ui_file_path, [appwindow])
window = builder.get_object(appwindow)
window.set_wmclass ("sign", "sign")
window.set_title("sign")
window.connect("delete-event", self.on_delete_window)
self.headerbar = window.get_titlebar()
self.header_button = builder.get_object("back_refresh_button")
self.header_button.connect('clicked', self.on_header_button_clicked)
sw = builder.get_object('stackswitcher1')
# I want to be able to press Alt+S and Alt+R respectively
# to switch the stack pages to Send and Receive.
# sw.get_children()
self.stack_switcher = sw
self.send_receive_stack = builder.get_object("send_receive_stack")
self.send_receive_stack.connect('notify::visible-child',
self.on_sr_stack_switch)
## Load Send part
self.send = SendApp()
ss = self.send.stack
p = ss.get_parent()
if p:
p.remove(ss)
ss.connect('notify::visible-child', self.on_send_stack_switch)
ss.connect('map', self.on_send_stack_mapped)
klw = self.send.klw
klw.connect("key-activated", self.on_key_activated)
klw.connect("map", self.on_keylist_mapped)
klw.props.margin_left = klw.props.margin_right = 15
self.send_stack = ss
## End of loading send part
# Load Receive part
self.receive = PswMappingReceiveApp(self.on_presign_mapped)
rs = self.receive.stack
rs.connect('notify::visible-child',
self.on_receive_stack_switch)
scanner = self.receive.scanner
scanner.connect("map", self.on_scanner_mapped)
self.receive_stack = rs
self.send_receive_stack.add_titled(self.send_stack,
"send_stack", _("Send"))
self.send_receive_stack.add_titled(rs,
"receive_stack", _("Receive"))
accel_group = Gtk.AccelGroup()
window.add_accel_group(accel_group)
self.receive.accept_button.add_accelerator("clicked", accel_group, ord('o'), Gdk.ModifierType.MOD1_MASK,
Gtk.AccelFlags.VISIBLE)
self.receive.accept_button.set_can_default(True)
window.show_all()
self.add_window(window)

Here's a hacky way to get to the first and last children of a stack with two children:
#!/usr/bin/env python
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GdkPixbuf, Gdk
import os, sys
class GUI:
def __init__(self):
self.stack = Gtk.Stack()
switcher = Gtk.StackSwitcher()
switcher.set_stack(self.stack)
label1 = Gtk.Label("label 1")
label2 = Gtk.Label("label 2")
label3 = Gtk.Label("label 3")
self.stack.add_titled (label1, "1", "Page 1")
self.stack.add_titled (label2, "2", "Page 2")
self.stack.add_titled (label3, "3", "Page 3")
box = Gtk.Box()
box.pack_start(switcher, True, False, 0)
box.pack_start(self.stack, True, True, 0)
box.set_orientation(Gtk.Orientation.VERTICAL)
window = Gtk.Window()
window.add(box)
window.show_all()
window.connect("key-press-event", self.key_press)
def key_press (self, window, event):
keyname = Gdk.keyval_name(event.keyval)
if not Gdk.ModifierType.CONTROL_MASK:
#only continue when the CTRL key is down
return
#get the last child
if keyname == "r":
for child in self.stack.get_children():
self.stack.set_visible_child(child)
#get the first child
if keyname == "s":
for child in self.stack.get_children():
self.stack.set_visible_child(child)
return
def on_window_destroy(self, window):
Gtk.main_quit()
def main():
app = GUI()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())
Here's a hacky way to scroll forward and backward through a stack with more than two children:
#!/usr/bin/env python
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GdkPixbuf, Gdk
import os, sys
class GUI:
def __init__(self):
self.stack = Gtk.Stack()
switcher = Gtk.StackSwitcher()
switcher.set_stack(self.stack)
label1 = Gtk.Label("label 1")
label2 = Gtk.Label("label 2")
label3 = Gtk.Label("label 3")
self.stack.add_titled (label1, "1", "Page 1")
self.stack.add_titled (label2, "2", "Page 2")
self.stack.add_titled (label3, "3", "Page 3")
box = Gtk.Box()
box.pack_start(switcher, True, False, 0)
box.pack_start(self.stack, True, True, 0)
box.set_orientation(Gtk.Orientation.VERTICAL)
window = Gtk.Window()
window.add(box)
window.show_all()
window.connect("key-press-event", self.key_press)
def key_press (self, window, event):
keyname = Gdk.keyval_name(event.keyval)
if not Gdk.ModifierType.CONTROL_MASK:
#only continue when the CTRL key is down
return
#forward scroll
#variable to capture the active widget
previous_child_active = False
if keyname == "r":
#iterate over the stack children
for child in self.stack.get_children():
if previous_child_active == True:
# the last widget was the one that was active
self.stack.set_visible_child(child)
#finished
return
#remember if the previous child was active
previous_child_active = self.stack.get_visible_child() == child
#reverse scroll
#variable to capture the last widget we iterated
previous_child = None
if keyname == "s":
#iterate over the stack children
for child in self.stack.get_children():
if self.stack.get_visible_child() == child and previous_child != None:
#this is the active widget, so we set the previous active
self.stack.set_visible_child(previous_child)
#finished
return
#remember the last widget
previous_child = child
def on_window_destroy(self, window):
Gtk.main_quit()
def main():
app = GUI()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())

Related

How do I scale this Gtk3 dialog box up by a constant factor?

I have this code for creating my own password dialog in Gtk. I need to scale it up by 2-3 times for the display it's going to be used on. How do I do this?
#!/usr/bin/env python3
import gi
import sys
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
class EntryDialog(Gtk.Dialog):
def __init__(self, labeltext=None):
super().__init__(title="Password", modal=True, focus_on_map=True)
content = self.get_content_area()
self.timeout_id = None
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
spacing=15, margin=30)
content.add(vbox)
if labeltext is None:
labeltext = "Please enter a password:"
label = Gtk.Label(labeltext)
vbox.pack_start(label, True, True, 0)
hbox = Gtk.Box(spacing=1)
self.entry = Gtk.Entry()
self.entry.set_text("")
self.entry.set_max_length(256)
self.entry.set_invisible_char('•')
self.entry.set_visibility(False)
hbox.pack_start(self.entry, True, True, 0)
self.show = Gtk.ToggleButton(label="show")
self.show.set_active(False)
hbox.pack_start(self.show, True, True, 0)
vbox.pack_start(hbox, True, True, 0)
#self.entry.connect("activate", lambda x: print("Enter"))
self.show.connect("toggled", self.on_show_toggled)
self.add_buttons(
Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK
)
self.set_default_response(Gtk.ResponseType.OK)
self.entry.connect("activate", self.on_entry_enter)
def on_show_toggled(self, button):
active = button.get_active()
self.entry.set_visibility(active)
button.set_label("hide" if active else "show")
def on_entry_enter(self, button):
self.activate_default()
def get_password(self):
return self.entry.get_text()
def run_dialog(argv):
if len(argv) == 1:
win = EntryDialog()
elif len(argv) == 2:
win = EntryDialog(argv[1])
else:
print(f"Usage: {argv[0]} [<prompt text>]", file=sys.stderr)
sys.exit(2)
win.show_all()
result = win.run()
if result == Gtk.ResponseType.OK:
print(win.get_password())
else:
sys.exit(1)
if __name__ == '__main__':
run_dialog(sys.argv)
Using the GDK_SCALE environment variable was suggested on IRC. This works for my use-case, but it seems a poor solution for general use. In my case, this is what I had to change my program to this:
#!/usr/bin/env python3
import sys
import os
if __name__ == '__main__':
scale = os.environ.get('GDK_SCALE', '1')
scale = float(scale) * 2.5
os.environ['GDK_SCALE'] = str(scale)
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
class EntryDialog(Gtk.Dialog):
def __init__(self, labeltext=None):
super().__init__(title="Password", modal=True, focus_on_map=True)
content = self.get_content_area()
self.timeout_id = None
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
spacing=15, margin=30)
content.add(vbox)
if labeltext is None:
labeltext = "Please enter a password:"
label = Gtk.Label(label=labeltext)
vbox.pack_start(label, True, True, 0)
hbox = Gtk.Box(spacing=1)
self.entry = Gtk.Entry()
self.entry.set_text("")
self.entry.set_max_length(256)
self.entry.set_invisible_char('•')
self.entry.set_visibility(False)
hbox.pack_start(self.entry, True, True, 0)
self.show = Gtk.ToggleButton(label="show")
self.show.set_active(False)
hbox.pack_start(self.show, True, True, 0)
vbox.pack_start(hbox, True, True, 0)
#self.entry.connect("activate", lambda x: print("Enter"))
self.show.connect("toggled", self.on_show_toggled)
self.add_buttons(
Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL,
Gtk.STOCK_OK, Gtk.ResponseType.OK
)
self.set_default_response(Gtk.ResponseType.OK)
self.entry.connect("activate", self.on_entry_enter)
def on_show_toggled(self, button):
active = button.get_active()
self.entry.set_visibility(active)
button.set_label("hide" if active else "show")
def on_entry_enter(self, button):
self.activate_default()
def get_password(self):
return self.entry.get_text()
def run_dialog(argv):
if len(argv) == 1:
win = EntryDialog()
elif len(argv) == 2:
win = EntryDialog(argv[1])
else:
print(f"Usage: {argv[0]} [<prompt text>]", file=sys.stderr)
sys.exit(2)
win.show_all()
result = win.run()
if result == Gtk.ResponseType.OK:
print(win.get_password())
else:
sys.exit(1)
if __name__ == '__main__':
run_dialog(sys.argv)
Note that I had to make sure the environment variable was set before I imported the gi package.

Alternating Switches ON/OFF?

So I want to have my small Python Gtk window have 2 switches. When one switch is ON, the other is turned OFF, and vice versa. I am not too sure how to control both switches. If anyone can lead me in the right direction, it'd be much appreciated.
#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
class SwitcherWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Alt Switch Demo")
self.set_border_width(10)
hbox = Gtk.Box(spacing=10)
self.add(hbox)
switch1 = Gtk.Switch()
switch1.connect("notify::active", self.on_switch_activated)
switch1.set_active(True)
hbox.pack_start(switch1, True, True, 0)
switch2 = Gtk.Switch()
switch2.connect("notify::active", self.on_switch_activated)
switch2.set_active(False)
hbox.pack_start(switch2, True, True, 0)
if switch1.get_active():
switch2.set_active(False)
else:
switch2.set_active(True)
def on_switch_activated(self, switch, gparam):
builder = Gtk.Builder()
sw1 = builder.get_object("switch1")
sw2 = builder.get_object("switch2")
if switch.get_active():
state = "on"
sw2.set_active(False)
else:
state = "off"
print("Switch was turned", state)
win = SwitcherWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
I would bind the properties of both switches, inverted and sync'ed on creation:
#!/usr/bin/python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject
class SwitcherWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Alt Switch Demo")
self.set_border_width(10)
hbox = Gtk.Box(spacing=10)
self.add(hbox)
switch1 = Gtk.Switch()
switch1.set_active(True)
hbox.pack_start(switch1, True, True, 0)
switch2 = Gtk.Switch()
switch2.set_active(False)
hbox.pack_start(switch2, True, True, 0)
switch1.bind_property("active", switch2, "active", GObject.BindingFlags.BIDIRECTIONAL | GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.INVERT_BOOLEAN)
win = SwitcherWindow()
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
The solution resides on this line of code:
switch1.bind_property("active", switch2, "active", GObject.BindingFlags.BIDIRECTIONAL | GObject.BindingFlags.SYNC_CREATE | GObject.BindingFlags.INVERT_BOOLEAN)
Here you bind the "active" property of switch1 and switch2 with the binding flags: bidirectional, sync on create and invert boolean
You can implement a similar logic to what I wrote:
#!/usr/bin/env python
class Switch:
_State = False
def __init__(self, StartingPosition=False):
self._State = StartingPosition
def SwitchON(self):
self._State = True
def SwitchOFF(self):
self._State = False
def Switch(self):
self._State = not self._State
def GetInfo(self):
print(self._State)
class Switcher:
def __init__(self, switchDependencyList=[]):
self.SwitchDependencyList = switchDependencyList
if len(self.SwitchDependencyList) == 0:
return None
if not len(self.SwitchDependencyList) % 2:
return None
def SwitchByIndex(self, Index):
for i, switch in enumerate(self.SwitchDependencyList):
if i == Index:
switch.SwitchON()
else:
switch.SwitchOFF()
def GetInfo(self):
for switch in self.SwitchDependencyList:
switch.GetInfo()
sw1 = Switch()
sw2 = Switch()
SwitcherModule = Switcher([sw1, sw2])
SwitcherModule.SwitchByIndex(1)
SwitcherModule.GetInfo()
No need for anything as complex as the prelisted answers. gtk already has a radiobutton widget that does it all for you. Only thing is that when it is initialised you have no buttons set, so you have to pick one to set.

GTK3 &Python interactive - architecture of classes - PopupMenu Of GTK3 on matplotlib Canvas

I am using Python & GTK3 under mac OS X Sierra in order to display a database of nodes as a Diagram. It is a MVP architecture.
I use matplotlib to display my figure. As my display is interactive so I have to receive signals. I decided to receive signals directly from my matplotlib canvas instead using GTK GUI, as GTK event do not have enough parameters. Actually I want to receive signals on my canvas using matplotlib and show a popup menu of GTK.
The function that you have to look is MainFigurePressed. The idea is I received signals on my canvas with the program DrawChronoMap using the function Detecte() than I popup a menu of my GTK GUI calling View by connecting Viewhandlers. In order to launch my program, my controller will call my view.I am wondering how can I pass in argument my class Viewhandler in my class DrawChronoMap?
How should I do? How should I change my architecture to do that?
I have three classes actually :
class View():
def __init__(self, MainController):
#set windows
self.window = Gtk.Window()
self.window.connect("delete-event", Gtk.main_quit)
self.window.set_default_size(10000, 10000)
self.window.set_title('ChronoMap')
#Init Glade file # Get windows from glade
self.interface = Gtk.Builder()
self.interface.add_from_file("interface1.glade")
self.mainWindow = self.interface.get_object("mainWindow")
self.aboutchronomap = self.interface.get_object("aboutchronomap")
self.fichierdialogue=self.interface.get_object("fichierdialogue")
self.sw=self.interface.get_object("mainFigure")
self.toolbar=self.interface.get_object("MatplotlibToolbar")
self.sw3=self.interface.get_object("scrolledwindow1")
self.sw4=self.interface.get_object("scrolledwindow2")
self.add_node_window=self.interface.get_object("add_node_window")
self.add_edge_window=self.interface.get_object("add_edge_window")
self.modify_edge_window=self.interface.get_object("modify_edge_window")
self.modify_node_window=self.interface.get_object("modify_node_window")
self.add_reference_node_edge=self.interface.get_object("add_reference_node_edge")
self.popupmenuCartoNode=self.interface.get_object("popupmenuCartoNode")
self.popupmenuCartoEdge=self.interface.get_object("popupmenuCartoEdge")
self.popupmenuCartoOtherplace=self.interface.get_object("popupmenuCartoOtherplace")
self.popupmenuChronoNode=self.interface.get_object("popupmenuChronoNode")
self.popupmenuChronoZoneBC=self.interface.get_object("popupmenuChronoZoneBC")
self.popupmenuChronoCursor=self.interface.get_object("popupmenuChronoCursor")
#Global controller
self.controller=MainController
#Init CartoCanvas
self.figCarto = Figure(figsize=(20,20), dpi=80)
self.axCarto = self.figCarto.add_subplot(111)
self.canvasCarto = FigureCanvas(self.figCarto)
# Init ChronoCanvas
self.figChrono = Figure(figsize=(20,20), dpi=80)
self.axChrono = self.figChrono.add_subplot(111)
self.canvasChrono = FigureCanvas(self.figChrono)
#Create a New graph on the controller
self.controller.create_new_graph("CartoChronomap")
#add node & edges
nodeA=self.controller.create_evenement("outdated research material", "01-01-2016 00:00:00", "01-02-2016 00:00:00", 1, "BLAH BLAH BLAH", "http://")
nodeB= self.controller.create_evenement("Projected tsunami frequency too low", "08-08-2016 00:00:00", "09-10-2016 00:00:00", 1, "OK", "http://")
nodeC=self.controller.create_evenement("EV C", "08-07-2016 00:00:00", "09-08-2016 00:00:00", 1, "HOOOOO", "http://")
nodeD=self.controller.create_evenement("Accident", "08-10-2016 00:00:00", "09-11-2016 00:00:00", 1, "HOOOOO", "http://")
self.controller.create_edge(nodeA,nodeB, "LeLien", "Une mega explosion", "[]")
self.controller.create_edge(nodeB,nodeA, "InverseLien", "Une giga explosion", "[]")
self.controller.create_edge(nodeC,nodeD, "LienTest", "Ceci est un lien test", "[]")
self.controller.calculate_position('spring_layout');
#Connect to draw chronograph
self.FdessinChrono=Draw_chrono.DrawChronoMap(self.axChrono,self.controller)
#Connect to draw Cartograph
self.FdessinCarto = Draw_cartograph.DrawCartoMap(self.axCarto, self.controller)
#draw
self.FdessinCarto.draw_cartograph()
self.FdessinChrono.draw_chronograph()
#MouseFunction Carto
self.FdessinCarto.zoom_wheel()
self.FdessinCarto.pan_drag()
#self.FdessinCarto.drag_node()
self.FdessinCarto.ChangeNodeColor()
self.FdessinCarto.node_popup_mouse_over()
self.FdessinCarto.edge_popup_mouse_over()
#Global carto event & chrono event
self.CartoEvent = self.FdessinCarto.Detect()
self.ChronoEvent = self.FdessinChrono.Detect()
print(self.CartoEvent,self.ChronoEvent)
#MouseFunction Chrono
self.FdessinChrono.cursor()
self.FdessinChrono.ChangeColor()
#self.FdessinChrono.pan_drag()
self.FdessinChrono.node_popup_mouse_over()
#Display Mode
self.display_Mode = None
#Creating the ListStore model
#node_liststore
self.node_liststore = Gtk.ListStore(str, str, str,str,str,str)
if len(self.FdessinCarto.pos) != 0:
for i,node in enumerate(self.FdessinCarto.pos):
self.node_liststore.append([str(node.title),str(node.start_time),str(node.end_time),str(node.node_group),str(node.description),str(node.attachment_list)])
#edge_liststore
self.edge_liststore = Gtk.ListStore(str, str, str,str,str)
if len(self.FdessinCarto.edgelist) !=0:
edge_prop=self.FdessinCarto.controller.edge_data(nodeA,nodeB)
edge_prop1=self.FdessinCarto.controller.edge_data(nodeB,nodeA)
self.edge_liststore.append([edge_prop['label'],str(nodeA.title),str(nodeB.title),edge_prop['description'],edge_prop['attachment_list']])
self.edge_liststore.append([edge_prop1['label'],str(nodeA.title),str(nodeB.title),edge_prop1['description'],edge_prop1['attachment_list']])
#creating the filtre
self.node_filter = self.node_liststore.filter_new()
self.edge_filter = self.edge_liststore.filter_new()
#setting the filter function, note that we're not using the
self.node_filter.set_visible_func(ViewHandler.node_filter_func)
self.edge_filter.set_visible_func(ViewHandler.edge_filter_func)
#creating the treeview for Node, making it use the filter as a model, and adding the columns
self.treeviewNode = Gtk.TreeView.new_with_model(self.node_liststore)
for i, column_title in enumerate(["Nom", "Date début", "Date fin", "Type de noeud", "Description du noeud","fichier"]):
self.Noderenderer = Gtk.CellRendererText()
self.Noderenderer.set_property("editable", True)
column = Gtk.TreeViewColumn(column_title, self.Noderenderer, text=i)
self.treeviewNode.append_column(column)
#self.Noderenderer.connect("edited", self.onButtonCreateNode)
#creating the treeview for edge
self.treeviewEdge = Gtk.TreeView.new_with_model(self.edge_liststore)
for i, column_title in enumerate(["Nom", "Noeud 1", "Noeud 2", "Description du lien","fichier"]):
self.Edgerenderer = Gtk.CellRendererText()
self.Edgerenderer.set_property("editable", True)
column = Gtk.TreeViewColumn(column_title, self.Edgerenderer, text=i)
self.treeviewEdge.append_column(column)
# Connect with signals
self.interface.connect_signals(ViewHandler(self))
#setting up the layout, putting the treeview in a scrollwindow
self.sw3.add(self.treeviewNode)
self.sw4.add(self.treeviewEdge)
self.sw3.show_all()
self.sw4.show_all()
self.window.add(self.sw)
self.sw.show_all()
# All ready - open interface
Gtk.main()
def update_data(self):
self.CartoEvent = self.FdessinCarto.Detect()
self.ChronoEvent = self.FdessinChrono.Detect()
print(self.CartoEvent,self.ChronoEvent)
class ViewHandler():
def __init__(self, ViewConnection):
self.View = ViewConnection
def resetplot(self):
axCarto.cla()
axCarto.set_xlim(0,10)
axCarto.set_ylim(0,10)
axCarto.grid(True)
axChrono.cla()
axChrono.set_xlim(0,10)
axChrono.set_ylim(0,10)
axChrono.grid(True)
# All button signals of GTK
#Signal to open windows "creation of node"
def create_node_button_press_event(self,widget):
self.View.add_node_window.show_all()
#Signal to open window "creation of link"
def create_link_button_press_event(self,widget):
self.View.add_edge_window.show_all()
def onButtonCreateNode(self,widget):
self.resetplot()
nom=self.View.interface.get_object('name_node1').get_text()
node_type=self.View.interface.get_object('node_type1').get_text()
start_time_node=self.View.interface.get_object('start_time_node1').get_text()
end_time_node=self.View.interface.get_object('end_time_node1').get_text()
#print(nom,node_type,start_time_node,end_time_node)
self.View.node_liststore.append([nom, start_time_node, end_time_node, node_type, "BLAH BLAH BLAH", "http://"])
self.View.FdessinCarto.controller.create_evenement(nom, start_time_node, end_time_node, node_type, "BLAH BLAH BLAH", "http://")
self.View.FdessinChrono.controller.create_evenement(nom, start_time_node, end_time_node, node_type, "BLAH BLAH BLAH", "http://")
self.View.canvasCarto.draw()
self.View.canvasChrono.draw()
self.View.add_node_window.destroy()
self.View.sw.show_all()
self.View.sw3.show_all()
def onButtonAddFileEdge(self,widget):
pass
def onButtonCreateEdge(self,widget):
nom=self.View.interface.get_object('name_edge2').get_text()
edge_description=self.View.interface.get_object('edge_type2').get_text()
node1_edge=self.View.interface.get_object('node1_edge_entry').get_text()
node2_edge=self.View.interface.get_object('node2_edge_entry2').get_text()
#create signal with liststore
self.View.edge_liststore.append([node1_edge,node2_edge, nom, edge_description, "[]"])
#create link with canvas
self.View.FdessinCarto.controller.create_edge(node1_edge,node2_edge, nom, edge_description, "[]")
self.View.FdessinChrono.controller.create_edge(node1_edge,node2_edge, nom, edge_description, "[]")
self.View.canvasCarto.draw()
self.View.canvasChrono.draw()
#register it in the treeStore
edge_prop=list(self.View.FdessinCarto.controller.edge_data(node1_edge,node2_edge))
self.View.sw.show_all()
self.View.add_edge_window.destroy()
#Signal to contextual menu
def onMainFigurePressed(self,widget,event):
print(event.type, event.button, event.window, event.x, event.y, event.time,event.get_state(),event.time)
#update event
self.View.update_data()
self.CartoEvent = self.View.FdessinCarto.Detect()
self.ChronoEvent = self.View.FdessinChrono.Detect()
print(self.View.CartoEvent,self.View.ChronoEvent,self.CartoEvent,self.ChronoEvent)
if event.type == Gdk.EventType.ENTER_NOTIFY:
print("yes, enter")
if event.type == Gdk.EventType.LEAVE_NOTIFY:
print("No, out")
if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 3:
if self.display_Mode == "carto" :
print("oui, carto " )
self.View.popupmenuCartoNode.popup(None, None, None, None, event.button, event.time)
elif self.display_Mode == "chrono" :
print( "oui chrono")
self.View.popupmenuChronoNode.popup(None, None, None, None, event.button, event.time)
else:
return None
def onButtonModifyNode(self,widget,event):
#print("modify windows show all")
self.View.modify_node_window.show_all()
def onButtonDeleteNode(self,widget,event):
#print("button pressed delete")
self.View.FdessinCarto.deleteNode()
def onButtonLinkNode(self,widget,event):
#print("hello")
self.View.add_edge_window.show_all()
def onButtonCopyNode(self,widget,event):
#print("copy")
self.View.FdessinCarto.copynode()
#print("copy it")
def onButtonOtherplaceCreateNode(self,widget,event):
self.View.add_node_window.show_all()
def onButtonAttributsNode(self,widget,event):
self.View.FdessinCarto.display_node_attributs()
#Signal of menubars
def on_node_file_button_press_event(self,widget):
self.View.add_node_window.show_all()
def on_create_edge_button_press_event(self,widget):
self.View.add_edge_window.show_all()
def on_Open_button_press_event(self,widget,event):
self.View.fichierdialogue.show_all()
#signal of about
def on_gtk_about_button_release_event(self,widget,event):
self.View.aboutchronomap.show_all()
# close window
def on_close_button_press_event(self,widget,event):
self.View.on_quit_button_press_event (widget,event)
def on_quit_button_press_event (self,widget,event):
#pop up menu
dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,Gtk.ButtonsType.OK_CANCEL, "Vous partez?")
dialog.format_secondary_text("Voulez vous toujours partir?")
response=dialog.run()
if response == Gtk.ResponseType.OK:
Gtk.main_quit()
elif response == Gtk.ResponseType.CANCEL:
dialog.destroy()
dialog.destroy()
return True
def on_confirmation_deletenode_button_press_event (self,widget,event):
#pop up menu
dialog = Gtk.MessageDialog(None, 0, Gtk.MessageType.INFO,Gtk.ButtonsType.OK_CANCEL, "Suppression du noeud?")
dialog.format_secondary_text("Voulez vous vraiment supprimer le noeud?")
response=dialog.run()
if response == Gtk.ResponseType.OK:
Gtk.main_quit()
elif response == Gtk.ResponseType.CANCEL:
dialog.destroy()
dialog.destroy()
return True
def on_mainWindow_destroy(self, widget):
Gtk.main_quit()
def on_carto_display_button_press_event(self,widget,event):
self.display_Mode = "carto"
child=self.View.sw.get_child()
child1 = self.View.toolbar.get_child()
#print(child)
if child != None:
self.View.toolbar.remove(child1)
self.View.sw.remove(child)
self.box.remove(self.View.canvasChrono)
self.box=Gtk.Box()
self.View.sw.add(self.box)
self.box.pack_start(self.View.canvasCarto, True, True, 0)
#Add toolbar
toolbar = NavigationToolbar(self.View.canvasCarto, self.View.window)
self.View.toolbar.add_with_viewport(toolbar)
self.View.sw.show_all()
def on_chrono_display_button_press_event(self,widget,event):
self.display_Mode= "chrono"
child = self.View.sw.get_child()
child1 = self.View.toolbar.get_child()
if child != None:
self.View.toolbar.remove(child1)
self.View.sw.remove(child)
self.box.remove(self.View.canvasCarto)
self.View.FdessinChrono.draw_chronograph()
self.box=Gtk.Box()
self.View.sw.add(self.box)
self.box.pack_start(self.View.canvasChrono, True, True, 0)
#Add toolbar
toolbar = NavigationToolbar(self.View.canvasChrono, self.View.window)
self.View.toolbar.add_with_viewport(toolbar)
self.View.sw.show_all()
class DrawChronoMap:
def __init__(self,ax, controller):
#Global controller
self.controller = controller
#Global graph
self.G = self.controller.total_graph()
#Global model
self.model=self.controller.model
#Global Axis
self.ax = ax
#Global figure
self.fig = self.ax.get_figure()
#Gloal canvas
self.canvas = self.ax.get_figure().canvas
#Global list
self.nodelist = self.controller.get_node_list()
self.edgelist=self.controller.get_edge_list()
#Global empty collection
#Global nodecollection
self.nodecollection=None
#Gloabl datanode
self.datanode = []
#Global empty list
self.eventnode_with_rectangle=[]
self.start_date=[]
self.end_date=[]
self.event_name=[]
#Global data axes
self.axis_x=[]
#Global label axis y
self.yticks = None
# Drag time
self.drag_time=0
self.press = []
self.drag_press = []
self.xdrag=0
self.ydrag=0
#event data
self.xdata=0
self.ydata=0
#event if we selecte edge
self.node1=None
self.node2=None
#cursor
self.ly = self.ax.axvline(color='k') # the vert line
self.txt = self.ax.text(0.7, 0.9, '', transform=self.ax.transAxes)
#Node attibute popup
self.popup = self.ax.text(0, 0, '', style='italic',bbox = {'facecolor':'y', 'alpha':0.5, 'pad':10})
#Edge attribute popup
self.popupedge = self.ax.text(0, 0, '', style='italic',bbox = {'facecolor':'y', 'alpha':0.5, 'pad':10})
def draw_chronograph(self):
#update graph
self.G = self.controller.total_graph()
#update data of nodecollection
self.nodelist = self.controller.get_node_list()
for i in range(len(self.nodelist)):
self.event_name.append(self.nodelist[i].title)
bottom = ((i-1)*0.5) + 1.0
width = self.nodelist[i].end_time - self.nodelist[i].start_time
left=self.nodelist[i].start_time
height=0.3
rectangle = self.ax.bar(left,height,width,bottom)
rectangle.bottom = bottom
rectangle.i = i
self.eventnode_with_rectangle.append([self.nodelist[i],rectangle])
self.nodelist[i].pos=i
self.datanode.append(self.nodelist[i].start_time)
self.datanode.append(self.nodelist[i].end_time)
#pos of i in the dictionnary
taille=len(self.event_name)
pos=arange(0.5,(taille+2)*0.5+0.5,0.5)
self.yticks=yticks(pos,self.event_name)
locsy,labelsy=self.yticks
self.ax.set_yticks(pos)
self.ax.set_yticklabels(labelsy, size='small')
self.ax.axis('tight')
self.ax.set_ylim(0, taille*0.5+0.5)
self.ax.grid(color = 'g', linestyle = ':')
font = font_manager.FontProperties(size='small')
self.ax.legend(loc=1,prop=font)
#format the x-axis
self.ax.set_xlim(min(self.datanode), max(self.datanode))
self.ax.xaxis.tick_top()
# Finish up
self.ax.invert_yaxis()
self.fig.autofmt_xdate()
#init cursor
self.ly.set_xdata((min(self.datanode)+ max(self.datanode))/2)
self.txt.set_text('y=%s' % ((min(self.datanode)+ max(self.datanode))/2))
self.canvas.draw()
def ChangeColor(self):
def on_press(event):
#update self.press
self.press=[]
x=event.xdata
y=event.ydata
self.press=[x,y]
#print(event.button)
if event.button == 1:
for i,rectangle in self.eventnode_with_rectangle:
if (i.start_time< self.press[0] <i.end_time) and ((i.pos-1)*0.5+1-0.15< self.press[1] <(i.pos-1)*0.5+1+0.15) :
rectangle=self.ax.barh(((i.pos-1)*0.5)+1.0, i.end_time - i.start_time, left=i.start_time, height=0.3, align='center', color='red', alpha = 0.75)
rectangle=self.ax.barh(((i.pos-1)*0.5)+1.0, i.end_time - i.start_time, left=i.start_time, height=0.3, align='center', color='blue', alpha = 0.75)
self.canvas.draw()
else :
return None
def on_release(event):
self.press = []
self.canvas.draw()
self.canvas.mpl_connect('button_press_event', on_press)
self.canvas.mpl_connect('button_release_event', on_release)
def Detect(self):
def event(event):
actual_node = None
x=event.xdata
y=event.ydata
for i,rectangle in self.eventnode_with_rectangle:
if (i.start_time<x<i.end_time) and ((i.pos-1)*0.5+1-0.15<y<(i.pos-1)*0.5+1+0.15) :
actual_node = i
break
print("function drawchrono %s" %actual_node)
return actual_node
self.canvas.mpl_connect('button_press_event', event)
import BasicModel as md
import View as vw
import networkx as nx
import matplotlib.pyplot as plt
import forceatlas.forceatlas as nxfa2
import undo
import re
import copy
class Controller:
def __init__(self, model):
"""
Initialization: Gets the model
:param model: Model class to use
"""
# Loads the model
self.model = model
if __name__ == '__main__':
# Init Model
MainModel = md.Model()
# Init Controller
MainController = Controller(MainModel)
# Init View
MainView = vw.View(MainController)
# Program Running.
I am going to add some pictures in order to better explain my problem.
Canvas embedded in my GTK environment
This is my GTK environment with the canvas (in white) using matplotlib to display things. My canvas is displayed with matplotlib. The canvas receives mouse events and it wil change the display of the canvas.
Display of the popup menu
We can see a popup menu here. So what is tricky here, it is NO LONGER my canvas which receives the event, but it is actually my GTK environment.
So the problem is here :
I want to display different menu depending on the type of object that I click on. I can do it easily if it is the canvas which receive event as I can directly calculate if the event is on a node or an edge, but if it is a GTK event, I can no longer detect if the event is on a node or on an edge.
So what should I do? should I build a new class in order to connect GTK event and canvas event?
Thanks

PythonGtk : expand NoteBook to fill the rest of my window

I am trying to resize my window using Python Gtk3, but I need to expand the Notebook object to fill the main window.
How could I make the notebook fill the rest of the window?
Like this:
Here is my code :
#!/usr/bin/python
# coding=utf-8
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, Gdk
class SearchDialog(Gtk.Dialog):
def __init__(self, parent):
Gtk.Dialog.__init__(self, "Something", parent,
Gtk.DialogFlags.MODAL, buttons=(
Gtk.STOCK_NEW, Gtk.ResponseType.OK,
Gtk.STOCK_CANCEL, Gtk.ResponseType.CANCEL))
self.set_default_size(400, 600)
box = self.get_content_area()
label = Gtk.Label("Insert text you want to search for:")
box.add(label)
# self.entry = Gtk.Entry()
# box.add(self.entry)
self.main_area = Gtk.Stack()
self.main_area.set_transition_type(Gtk.StackTransitionType.SLIDE_LEFT_RIGHT)
self.main_area.set_transition_duration(1000)
self.entry = Gtk.Entry()
self.main_area.add_titled(self.entry, "entry_name", "Entry Url")
self.labelS = Gtk.Label()
self.label_txt = """<big><i> label here</i></big>"""
self.labelS.set_markup(self.label_txt)
self.labelS.set_line_wrap(True)
self.main_area.add_titled(self.labelS, "label_name", "How Scan will Start")
self.our_stackSwitcher = Gtk.StackSwitcher()
self.our_stackSwitcher.set_stack(self.main_area)
box.add(self.our_stackSwitcher)
box.add(self.main_area)
self.show_all()
class MyWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Desktop app title")
self.set_default_size(1000, 648)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
self.add(vbox)
Hbox1 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
vbox.add(Hbox1)
Hbox2 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
vbox.add(Hbox2)
Hbox3 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
vbox.add(Hbox3)
Hbox4 = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
vbox.add(Hbox4)
main_menu_bar = Gtk.MenuBar()
#################################################################################
#drop down the menu
file_menu1 = Gtk.Menu()
file_menu1_dropdown = Gtk.MenuItem("File")
#File menu Items
file_new = Gtk.MenuItem("New Scan")
file_save = Gtk.MenuItem("Save History")
file_exit = Gtk.MenuItem("Exit")
file_menu1_dropdown.set_submenu(file_menu1)
file_menu1.append(file_new)
file_new.connect("activate", self.Onclick_new)
file_menu1.append(file_save)
file_save.connect("activate", self.Onclick_save)
file_menu1.append(Gtk.SeparatorMenuItem())
file_menu1.append(file_exit)
file_exit.connect("activate",self.Onclick_exit)
#add the menu to the main menu bar
main_menu_bar.append(file_menu1_dropdown)
###################################################################################
#drop down the menu
file_menu2 = Gtk.Menu()
file_menu2_dropdown = Gtk.MenuItem("Scan")
#File menu Items
file_edit = Gtk.MenuItem("Edit")
file_cancel = Gtk.MenuItem("Cancel")
file_menu2_dropdown.set_submenu(file_menu2)
file_menu2.append(file_edit)
file_edit.connect("activate", self.Onclick_edit)
file_menu2.append(file_cancel)
file_cancel.connect("activate", self.Onclick_cancel)
#add the menu to the main menu bar
main_menu_bar.append(file_menu2_dropdown)
###################################################################################
#drop down the menu
file_menu3 = Gtk.Menu()
file_menu3_dropdown = Gtk.MenuItem("Help")
#File menu Items
file_mode = Gtk.MenuItem("Mode")
file_about = Gtk.MenuItem("About")
file_menu3_dropdown.set_submenu(file_menu3)
file_menu3.append(file_mode)
file_mode.connect("activate", self.Onclick_mode)
file_menu3.append(file_about)
file_about.connect("activate", self.Onclick_about)
#add the menu to the main menu bar
main_menu_bar.append(file_menu3_dropdown)
###################################################################################
## ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ##
Hbox1.pack_start(main_menu_bar , True, True, 0)
label1_Hbox2 = Gtk.Label(" i am label 1 of Horizental box 2")
Hbox2.pack_start(label1_Hbox2 , True, True, 0)
label2_Hbox2 = Gtk.Label(" i am label 2 of Horizental box 2")
Hbox2.pack_start(label2_Hbox2, True, True, 0)
self.notebook1 = Gtk.Notebook()
Hbox3.pack_start(self.notebook1, True, True, 0)
self.notebook2 = Gtk.Notebook()
Hbox3.pack_start(self.notebook2, True, True, 0)
##################################################################################################
self.page1 = Gtk.Box()
self.page1.set_border_width(3)
self.label = Gtk.Label('label Number 1-------')
self.page1.add(self.label)
self.label2 = Gtk.Label('label Number 2 should appear in next line')
self.page1.add(self.label2)
self.notebook1.append_page(self.page1, Gtk.Label('Tab Pane 1 panel 1'))
###################################################################################################
self.page1 = Gtk.Box()
self.notebook2.append_page(self.page1, Gtk.Label('Tab Pane 1 panel 2'))
self.page2 = Gtk.Box()
self.notebook2.append_page(self.page2, Gtk.Label('Tab Pane 2 panel 2'))
def Onclick_new(self, widget):
dialog = SearchDialog(self)
response = dialog.run()
if response == Gtk.ResponseType.OK:
self.label.set_text(dialog.entry.get_text())
dialog.destroy()
def Onclick_save(self, widget):
print("Save clicked")
def Onclick_exit(self, widget):
print("exit clicked")
Gtk.main_quit()
def Onclick_edit(self, widget):
print("Edit clicked")
def Onclick_cancel(self, widget):
print("Cancel clicked")
def Onclick_mode(self, widget):
print("Mode of use clicked")
def Onclick_about(self, widget):
print("About clicked")
#cssProvider = Gtk.CssProvider()
#cssProvider.load_from_path('gtkStyledButtonTest.css')
#screen = Gdk.Screen.get_default()
#styleContext = Gtk.StyleContext()
#styleContext.add_provider_for_screen(screen, cssProvider,
# Gtk.STYLE_PROVIDER_PRIORITY_USER)
win = MyWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()

How to disable the close button in GTK?

I have created a One Time Password mechanism in OpenERP 6.0.3's GTK client. After login the GTK client shows a window to enter the One Time Password as below.
Now I want to disable the close button at the top left of the window. How can I do that? I am using python and the code to create the window is:
EDIT
class sms_auth(gtk.Dialog):
def run_thread(self):
code=self.textbox_code.get_text()
self.result = rpc.session.rpc_exec_auth('/object', 'execute', 'res.users', 'check_code', code)
return self.result
def run(self):
self.show_all()
res = super(sms_auth, self).run()
result = None
if res == gtk.RESPONSE_ACCEPT:
result = self.run_thread()
self.destroy()
return result
def hide(*args):
window.hide()
return gtk.TRUE
def __init__(self, parent, response):
# To use cancel butto add gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
gtk.Dialog.__init__(
self, 'Sms Authentication', parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
)
label = gtk.Label("Please enter sms code :")
self.parent_widget = parent
self.response = False
self.db_login_response = response
self.connect('delete_event', hide)
self.textbox_code = gtk.Entry()
label.set_alignment(0,0)
table = gtk.Table(1, 7)
table.set_homogeneous(False)
table.set_col_spacings(40)
table.attach(label, 0, 6, 0, 1, ypadding=4)
table.attach(self.textbox_code, 5, 6, 0, 1, ypadding=4)
self.vbox.pack_start(table,False, False, 0)
Try like this
def hide(self, *args):
window.hide()
return gtk.TRUE
self.window.connect('delete_event', self.hide)
Note: Refer here
import pygtk
pygtk.require('2.0')
import gtk
class DialogExample(gtk.Dialog):
def __init__(self, parent=None):
gtk.Dialog.__init__(self, "My Dialog", parent,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
(gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
)
self.set_default_size(150, 100)
label = gtk.Label("This is a dialog to display additional information")
box = self.get_content_area()
box.add(label)
self.show_all()
self.connect('delete-event', self.delete_event)
def delete_event(self, widget, event=None):
print "Here"
return True
def main():
# rest in gtk_main and wait for the fun to begin!
gtk.main()
return 0
if __name__ == "__main__":
DialogExample()
main()

Categories

Resources