How to disable the close button in GTK? - python

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()

Related

Strange visual bug happening on QFocusEvents in my child QLineEdit

I'm making this class to make my QEditLines to have a default value, that will work as a label for the line, it seems to be working, but when changing the focus with 'Tab' the line will add a '|' at the end of the line and keep it until restarting and it's just visual, it doesn't change the Entry's value.
My child class of QLineEdit:
class Entry(QtWidgets.QLineEdit):
def __init__(self, frame: QtWidgets.QFrame):
super(Entry, self).__init__(frame)
self.default_text = ''
#QtCore.pyqtSlot(QtGui.QFocusEvent)
def focusInEvent(self, a0: QtGui.QFocusEvent) -> None:
if self.text() == self.default_text:
self.clear()
if 'PASSWORD' in self.default_text:
self.setEchoMode(self.Password)
#QtCore.pyqtSlot(QtGui.QFocusEvent)
def focusOutEvent(self, a0: QtGui.QFocusEvent) -> None:
if self.text() == "":
self.setText(self.default_text)
if 'PASSWORD' in self.default_text:
self.setEchoMode(self.Normal)
can be reproducible with a simple GUI with the code below:
def print_value(entry: Entry, entry2: Entry):
print(entry.text())
print(entry2.text())
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
root = QtWidgets.QMainWindow()
root.resize(500,500)
frame = QtWidgets.QWidget(root)
frame.resize(500,500)
entry = Entry(frame)
entry.setGeometry(QtCore.QRect(0, 0, 100, 50))
entry.setText('PASSWORD')
entry.default_text = 'PASSWORD'
entry2 = Entry(frame)
entry2.setGeometry(QtCore.QRect(0, 100, 100, 50))
entry2.setText('USERNAME')
entry2.default_text = 'USERNAME'
button = QtWidgets.QPushButton(frame)
button.setGeometry(QtCore.QRect(0, 200, 50, 50))
button.pressed.connect(lambda: print_value(entry, entry2))
root.show()
sys.exit(app.exec_())
In the terminal is the output of the values in the Entry objects, Password, and USERNAME QLineEdits. [Screenshot]
The default implementation of focusInEvent and focusOutEvent has the task of enabling and disabling the cursor, but by override those methods you are eliminating that behavior. One possible solution is to also invoke the default implementation:
class Entry(QtWidgets.QLineEdit):
def __init__(self, frame: QtWidgets.QFrame):
super(Entry, self).__init__(frame)
self.default_text = ""
def focusInEvent(self, a0: QtGui.QFocusEvent) -> None:
if self.text() == self.default_text:
self.clear()
if "PASSWORD" in self.default_text:
self.setEchoMode(self.Password)
super().focusInEvent(a0)
def focusOutEvent(self, a0: QtGui.QFocusEvent) -> None:
if self.text() == "":
self.setText(self.default_text)
if "PASSWORD" in self.default_text:
self.setEchoMode(self.Normal)
super().focusOutEvent(a0)

How do I use keyboard shortcuts with Gtk StackSwitcher?

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())

Passing Information from a child to a parent on an event

I have created a custom matplotlib toolbar, and I'm working on the functions associated with the custom toolbar's buttons. One of the buttons functions will (eventually) return a list position that best represents a user's selected position from a plot. I was having a bit of difficulty making this work in my mind, so I made a simple example (trying to avoid using globals) where a label not associated with the toolbar is updated when the toolbar button is pressed.
class TrackPlotToolbar(NavigationToolbar2TkAgg):
toolitems = [t for t in NavigationToolbar2TkAgg.toolitems if
t[0] in ('Home', 'Pan', 'Zoom', 'Save')]
toolitems.append(('Trace', 'Trace Track Position', 'Trace', 'Trace_old'))
def __init__(self, plotCanvas, frame):
self.TraceListOld = []
self.TraceListNew = []
NavigationToolbar2TkAgg.__init__(self, plotCanvas, frame)
def set_message(self, msg):
pass
def Trace_old(self):
gui.infoLabel.text = "abrakadabra"
gui.infoLabel.update()
return 1
class gui(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.grid()
self.parent = parent
self.infoLabel = Label(master = self, text = 'magic')
self.initUI()
def initUI(self):
TestPlot = FigureCanvasTkAgg(TestFig, self)
TestPlot.get_tk_widget().grid(column = 0,\
row = 0, columnspan = 3, rowspan = 5)
TestFrame = Frame(self)
TestFrame.grid(column = 2, row =6, columnspan = 3)
shockToolbar = TrackPlotToolbar(TestPlot,TestFrame)
shockToolbar.update()
self.infoLabel.grid(column = 2, row = 7)
def main():
root = Tk()
app = gui(root)
root.mainloop()
if __name__ == '__main__':
main()
Am I taking the wrong approach? Is it possible to inquire for new data on an event associated with a class inside of the parent class?

PyGTK The function takes exactly 1 argument (2 given)

I am trying to write a function to write text to a terminal window inside my application. But I am getting the above error.
Here's some of my code. This is GUI to play midi files. I am trying to display Opened file in my terminal window :
import pygtk
pygtk.require('2.0')
import gtk
import signal
import pango
import subprocess
textview = gtk.TextView()
class Teacher:
result = ""
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(400, 200)
window.set_title("The Improvisor")
window.connect("delete_event",
lambda w,e: gtk.main_quit())
table = gtk.Table(4, 4, True)
window.add(table)
button1 = gtk.Button("Open")
button1.connect("clicked", self.clicked_open_file)
button1.show()
button2 = gtk.Button("Play")
button2.connect("clicked", self.clicked_play)
button2.show()
button3 = gtk.Button("Stop")
button3.connect("clicked", self.clicked_stop)
button3.show()
fontdesc = pango.FontDescription('monospace')
textview.modify_font(fontdesc)
scroll = gtk.ScrolledWindow()
scroll.add(textview)
textview.show()
table.attach(button1, 0, 1, 0, 1)
table.attach(button2, 0, 1, 1, 2)
table.attach(button3, 0, 1, 2, 3)
table.attach(button4, 0, 4, 3, 4)
table.attach(scroll, 1, 4, 0, 3)
window.show_all()
def clicked_play(self, widget):
result = self.result
if result == "":
parent = None
alert = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT, gtk.MESSAGE_INFO,
gtk.BUTTONS_CLOSE, "Please Select a File")
alert.run()
alert.destroy()
else :
self.proc = subprocess.Popen(["timidity", result])
def clicked_open_file(self, widget):
chooser = gtk.FileChooserDialog(title="Open a file",action=gtk.FILE_CHOOSER_ACTION_OPEN,
buttons=(gtk.STOCK_CANCEL,gtk.RESPONSE_CANCEL,gtk.STOCK_OPEN,gtk.RESPONSE_OK))
response = chooser.run()
self.result = chooser.get_filename()
self.insert_text(self.result)
chooser.destroy()
def clicked_stop(self, widget=None):
if self.proc:
self.proc.terminate()
self.proc.wait()
def insert_text(text):
textview.get_buffer().insert_at_cursor(text)
def main(self):
signal.signal(signal.SIGTERM, self.clicked_stop)
gtk.main()
return 0
Teacher().main()
Your insert_text method lacks the self attribute. Change it to:
def insert_text(self, text):
...
Remember: the self argument in Python is the current instance of the class and must be declared explicitly as the first argument of a method.

PyQt: Call a TrayMinimized application

I have an application wich is minimized to the tray (showing an icon) when the user close it. What I need to know is how can I call it back with a combination of keys, like Ctrl+Alt+Something. Actually I call it back when I double-click it, but it will be nice to do the same on a keystroke. Here is a portion of the code:
# -*- coding: utf-8 -*-
"""The user interface for our app"""
import os,sys
import ConfigParser
# Import Qt modules
from PyQt4 import QtCore,QtGui
# Import the compiled UI module
from octo import Ui_Form
CFG_PATH = "etc/config.list" #Config File Path
#config.list vars DEFAULT Values
ClipCount = 8
Static = ""
window = None
# Create a class for our main window
class Main(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
# This is always the same
self.ui=Ui_Form()
self.ui.setupUi(self)
# Window Icon
icon = QtGui.QIcon("SSaver.ico")
self.setWindowIcon(icon)
self.setWindowTitle("Octopy")
# Set the timer =)
self.timer = self.startTimer(1000) #self.killTimer(self.timer)
# Clipboard Counter
self.counter = 0
#Last trapped clipboard
self.LastClip = ""
self.tentacles = [""] * 8
self.cmd = []
self.cmd.append(self.ui.cmd_1)
self.cmd.append(self.ui.cmd_2)
self.cmd.append(self.ui.cmd_3)
self.cmd.append(self.ui.cmd_4)
self.cmd.append(self.ui.cmd_5)
self.cmd.append(self.ui.cmd_6)
self.cmd.append(self.ui.cmd_7)
self.cmd.append(self.ui.cmd_8)
## Events ##
def on_cmd_8_pressed(self): #Clear
for i in range(0,7):
self.tentacles[i] = ""
self.cmd[i].setText(self.tentacles[i])
def on_cmd_1_pressed(self):
t = self.ui.cmd_1.text()
self.setClp(t)
def on_cmd_2_pressed(self):
t = self.ui.cmd_2.text()
self.setClp(t)
def on_cmd_3_pressed(self):
t = self.ui.cmd_3.text()
self.setClp(t)
def on_cmd_4_pressed(self):
t = self.ui.cmd_4.text()
self.setClp(t)
def on_cmd_5_pressed(self):
t = self.ui.cmd_5.text()
self.setClp(t)
def on_cmd_6_pressed(self):
t = self.ui.cmd_6.text()
self.setClp(t)
def on_cmd_7_pressed(self):
t = self.ui.cmd_7.text()
self.setClp(t)
def hideEvent(self,event): # Capture close and minimize events
pass
def keyPressEvent(self,ev):
if ev.key() == 16777216:
self.hide()
def showEvent(self,ev):
self.fillClp()
def timerEvent(self,ev):
c = self.getClp()
if c:
#print c, self.counter
self.tentacles[self.counter] = c
if self.counter < 7:
self.counter += 1
else:
self.counter = 0
self.fillClp()
## Functions ##
def fillClp(self):
for i in range(0,7):
self.cmd[i].setText(self.tentacles[i])
def getClp(self):
clp = QtGui.QApplication.clipboard()
c = clp.text()
if self.LastClip != c:
self.LastClip = c
return c
else:
return None
def setClp(self, t):
clp = QtGui.QApplication.clipboard()
clp.setText(t)
class SystemTrayIcon(QtGui.QSystemTrayIcon):
def __init__(self, icon, parent=None):
QtGui.QSystemTrayIcon.__init__(self, icon, parent)
menu = QtGui.QMenu(parent)
# Actions
self.action_quit = QtGui.QAction("Quit", self)
self.action_about = QtGui.QAction("About Octopy", self)
# Add actions to menu
menu.addAction(self.action_about)
menu.addSeparator()
menu.addAction(self.action_quit)
# Connect menu with signals
self.connect(self.action_about, QtCore.SIGNAL("triggered()"), self.about)
self.connect(self.action_quit, QtCore.SIGNAL("triggered()"), self.quit)
# Other signals
traySignal = "activated(QSystemTrayIcon::ActivationReason)"
QtCore.QObject.connect(self, QtCore.SIGNAL(traySignal), self.icon_activated)
# Create Menu
self.setContextMenu(menu)
def quit(self):
w = QtGui.QWidget()
reply = QtGui.QMessageBox.question(w, 'Confirm Action',"Are you sure to quit?", QtGui.QMessageBox.Yes, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
QtGui.QApplication.quit()
def about(self):
w = QtGui.QWidget()
QtGui.QMessageBox.information(w, 'About', "Octopy Multi-Clipboard Manager\n Developed by mRt.")
def icon_activated(self, reason):
if reason == QtGui.QSystemTrayIcon.DoubleClick:
window.show()
else:
print "otro"
def main():
# Again, this is boilerplate, it's going to be the same on
# almost every app you write
app = QtGui.QApplication(sys.argv)
# TrayIcon
w = QtGui.QWidget()
icon = QtGui.QIcon("SSaver.ico")
trayIcon = SystemTrayIcon(icon, w)
trayIcon.show()
trayIcon.setToolTip("Octopy Multi-Clipboard Manager")
# Main Window
global window
window=Main()
window.show()
window.setWindowTitle("Octopy")
app.setQuitOnLastWindowClosed(0)
sys.exit(app.exec_())
def readIni():
cfg = ConfigParser.ConfigParser()
cfg.read(CFG_PATH)
ClipCount = int(cfg.get("Other","ClipCount"))
Static = cfg.get("Other","Static")
clip = [""] * int(ClipCount+1)
if __name__ == "__main__":
readIni()
main()
The complete program is hosted on google: http://code.google.com/p/octopys/downloads/list
For a keystroke to be handled by your application when it does not have keyboard focus, you need to install a global shortcut. Qt doesn't support this, but Qxt, a Qt extension library, does. See
http://doc.libqxt.org/0.5.0/classQxtGlobalShortcut.html. I don't know if PyQt bindings exist for Qxt.

Categories

Resources