I have very simple window where I have 2 buttons - one for cancel, one for apply. How to set the button for apply as default one? (When I press enter, "apply" button is pressed)
However, I want to set focus to the first input widget (I can't use grab_focus() on the button)
Any suggestions?
Edit:
After wuub's answer it works visually good. However, when I press the button in different widget, it doesn't run callback of the default button.
Example code:
import os, sys, pygtk, gtk
def run(button, window):
dialog = gtk.MessageDialog(window, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, "OK")
dialog.run()
dialog.destroy()
window = gtk.Window()
window.connect("destroy", gtk.main_quit)
vbox = gtk.VBox(spacing = 10)
entry = gtk.Entry()
vbox.pack_start(entry)
button = gtk.Button(stock = gtk.STOCK_SAVE)
button.connect("clicked", run, window)
button.set_flags(gtk.CAN_DEFAULT)
window.set_default(button)
vbox.pack_start(button)
window.add(vbox)
window.show_all()
gtk.main()
EDIT2: Every input which can activate default widget must be ran
widget.set_activates_default(True)
http://www.pygtk.org/docs/pygtk/class-gtkdialog.html#method-gtkdialog--set-default-response
http://www.pygtk.org/docs/pygtk/class-gtkwindow.html#method-gtkwindow--set-default
Related
When I press the Key Enter in the lineEdit box performs both function enter_LineEdit() and function click_Edit(). Why does it perform function click_Edit()? It must not!
I would like someone to explain to me why does it work this way?
#!/usr/bin/python3.6
# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QMainWindow,QApplication,QPushButton,QDialog,QHBoxLayout,QLabel,QWidget,QLineEdit
from PyQt5 import QtGui
from PyQt5 import QtCore
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(100,100,600,400)
self.CreateBtn()
self.show()
def CreateBtn(self):
button = QPushButton("Second Window", self)
button.setGeometry(QtCore.QRect(30,100,200,80))
button.setIconSize(QtCore.QSize(70,70))
button.clicked.connect(self.SecWin)
def SecWin(self):
self.d = SecondWindow()
self.d.Create_SecWin()
self.d.Create_Object()
self.d.Create_Layout()
class SecondWindow(QDialog):
def Create_SecWin(self):
self.setGeometry(600,360,400,100)
self.show()
def Create_Object(self):
self.btnEdit = QPushButton("Edit",self)
self.btnEdit.clicked.connect(self.click_Edit)
self.labelSearch = QLabel("Search:",self)
self.lineEdit = QLineEdit(self)
self.lineEdit.returnPressed.connect(self.enter_LineEdit)
def Create_Layout(self):
hbox1 = QHBoxLayout()
hbox1.addWidget(self.btnEdit)
hbox1.addWidget(self.labelSearch)
hbox1.addWidget(self.lineEdit)
self.setLayout(hbox1)
def click_Edit(self):
print("Philip")
def enter_LineEdit(self):
print("Karl")
App = QApplication(sys.argv)
window = Window()
sys.exit(App.exec_())
If you review the docs of the autoDefault property of QPushButton:
This property holds whether the push button is an auto default button
If this property is set to true then the push button is an auto
default button.
In some GUI styles a default button is drawn with an extra frame
around it, up to 3 pixels or more. Qt automatically keeps this space
free around auto-default buttons, i.e., auto-default buttons may have
a slightly larger size hint.
This property's default is true for buttons that have a QDialog
parent; otherwise it defaults to false.
See the default property for details of how default and auto-default
interact.
And also from the default property:
[...]
A button with this property set to true (i.e., the dialog's default
button,) will automatically be pressed when the user presses enter,
with one exception: if an autoDefault button currently has focus, the
autoDefault button is pressed. When the dialog has autoDefault buttons
but no default button, pressing enter will press either the
autoDefault button that currently has focus, or if no button has
focus, the next autoDefault button in the focus chain.
[...]
That is, some of the QPushButtons will be pressed when the enter key is pressed in a QDialog since all QPushButtons have the autoDefault property in True, so the solution is to set it to False:
self.btnEdit = QPushButton("Edit", self)
self.btnEdit.setAutoDefault(False)
i have a big problem (for me!) with python gtk module.
i can open multi windows; but i can't close singly ( one time , one window ).
if i close a window, all windows close automatically.
i want to close the first window only. after closing firt window, come a new window ( by my choice).
for example :
#!/usr/bin/env python
import pygtk
pygtk.require20()
import gtk
class CLS1(object):
def __init__(self):
self.mywindow = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.mywindow.connect("delete_event", gtk.main_quit)
self.btn = gtk.Button("Cls1|Btn")
self.mywindow.add(self.btn)
self.mywindow.show_all()
def main(self):
gtk.main()
class CLS2(object):
def __init__(self):
self.mywindow = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.mywindow.connect("delete_event", gtk.main_quit)
self.btn = gtk.Button("Cls2|Btn")
self.mywindow.add(self.btn)
self.mywindow.show_all()
def main(self):
gtk.main()
class APP(object):
def __init__(self):
self.mywindow = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.mywindow.connect("delete_event", gtk.main_quit)
self.hori = gtk.HBox()
self.btn1 = gtk.Button("AppBtn1")
self.btn2 = gtk.Button("AppBtn2")
self.btn1.connect("clicked", self.show_me , "AppBtn1")
self.btn2.connect("clicked", self.show_me , "AppBtn2")
self.hori.pack_start(self.btn1)
self.hori.pack_start(self.btn2)
self.mywindow.add(self.hori)
self.mywindow.show_all()
def show_me(self, penar, data):
if data=="AppBtn1" :
CLS1().main()
if data=="AppBtn2":
CLS2().main()
gtk.main_quit()
def main(self):
gtk.main()
APP().main()
i want this :
1- i will run the program
2- the "APP" class will work and will come "APP" window
3- if i click a button (AppBt1 or AppBtn2) ; the "APP" window will close (automatically ; not by me!)
4- if i was clicked "AppBtn1" button on "APP" window (#step 3) ; the "CLS1" class will work and its window will open
,or if i was clicked "AppBtn2" button on "APP" window (#step 3) ; the "CLS2" class will work and its window will open
i wanna only one window on the screen while program running; if i click a button ; its window will close and a new window will open (by my choice, and automatically!)
how can i do this? and can you write its code :)
thanks a lot !
Calling gtk.main_quit will kill the whole program (it basically stop GTK). So what you need, is just to stop GTK when the last window has been closed. What you're currently doing is stopping GTK when any window is closed.
So just use a global variable that you will use as a counter of the windows open. On the delete-event handler, decrement that counter, and if it reached 0 that means you have no more windows open, and you can call gtk.main_quit, otherwise, do nothing and the window will just be normally destroyed.
To kill the parent window, just pass the parent as the last parameter when you connect to the clicked signal. In the associated callback, you'll get that last parameter and call gtk.Widget.destroy on it.
Well a better way might be to modify the window that's already open instead of closing it and opening another.
I am working with buttons in Tkinter, Python.
The thing is when I click in one button the text of the button shakes. It might be a default behavior for this widget and I don't know how to disable it and make it static.
I assume that you mean the relief change from raised to sunken when you click a button.
This is what I found on http://wiki.tcl.tk/1048 (click 'Show Discussion' to see it):
Unfortunately, the relief used when you click is hardcoded (as
'sunken'), so you can't configure it per-widget without hacking the Tk
internals for the binding for buttons.
So the simplest way around this would be to always make the button appear sunken
MyButton = Tkinter.Button(
self.frame,
text = "Foobar",
command = self.foobar,
relief=Tkinter.SUNKEN
)
The disadvantage of that is that it might make the button look unresponsive.
You can also use a widget other than a button to be used as a clickable item (suggested by Joel Cornett). Here is a simple example with a label used as a button:
import Tkinter
class main:
def __init__(self,root):
# make a label with some space around the text
self.lbl1 = Tkinter.Label(root,
width = 16, height = 4,
text = "Foobar")
self.lbl1.pack()
# Call a function when lbl1 is clicked
# <Button-1> means a left mouse button click
self.lbl1.bind("<Button-1>", self.yadda)
self.lbl1.bind("<Enter>", self.green)
self.lbl1.bind("<Leave>", self.red)
def yadda(self, event):
self.lbl1.config(text="Clicked!")
def green(self, event):
self.lbl1.config(bg="green")
def red(self,event):
self.lbl1.config(bg="red")
if __name__ == "__main__":
root = Tkinter.Tk()
main(root)
root.mainloop()
i have 10 button, which correspond to the same method. how am i going to check which button was clicked in the corresponding method? i tried to check for the button press of a particular button in the list by the following code, but i got segmentation fault error:
for i in range(0,10):
if button_list[i].clicked():
break
break
#operation with respect to the button clicked
Here's a sample code that illustrates knowing what button triggered the event by using the label of the button:
from gi.repository import Gtk
class ButtonWindow(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Button Demo")
self.set_border_width(10)
hbox = Gtk.Box(spacing=6)
self.add(hbox)
#Lets create 10 buttons for this demo
#You could create and set the label for
#each of the buttons one by one
#but in this case we just create 10
#and call them Button0 to Button9
for i in range(10):
name = "Button{}".format(i)
button = Gtk.Button(name)
button.connect("clicked", self.on_button_clicked)
hbox.pack_start(button, True, True, 0)
def on_button_clicked(self, button):
print button.get_label()
def on_close_clicked(self, button):
print "Closing application"
Gtk.main_quit()
win = ButtonWindow()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
So you could just check what the label is and act accordingly.
Once you have connected all the buttons to the same callback, I assume the callback will have this signature: callback(button) where button is the button that emitted the clicked signal.
Inside that callback should be easy to check which button was clicked using something like:
button_list.index(button)
This will return the index of the button inside your list.
I've got a small PyGTK program, that has a statusicon. Upon left click on the statusicon a window with a TextView should appear and a predefined text should be shown in the TextView widget. My problem is that I don't know how to pass the text to shown as a parameter to the method that creates the window. I can create the window with a TextView without problems, but I cannot insert text into it.
Here's my code:
import gtk
import keybinder
class PyPPrinter(object):
def __init__(self):
self.staticon = gtk.StatusIcon()
self.staticon.set_from_stock(gtk.STOCK_INDEX)
self.staticon.set_visible(True)
self.staticon.connect('activate', self.browser(output_text = 'text'))
gtk.main()
def browser(self, window, output_text):
browser = gtk.Window()
browser.set_usize(600, 500)
textbox = gtk.TextView()
text = gtk.TextBuffer()
text.set_text(output_text)
textbox.set_buffer(text)
browser.add(textbox)
browser.show_all()
if __name__ == '__main__':
PyPPrinter()
This code gives me an exception: TypeError: browser() takes exactly 3 arguments (2 given). Perhaps I should also pass a value for the window parameter, but what should it be?
Two variants:
Change connect part:
self.staticon.connect('activate', self.browser(output_text = 'text'))
to:
self.staticon.connect('activate', self.browser, 'text')
or change Handler-Signature:
def browser(self, window, output_text):
to:
def browser(self, window):