python gtk.entry() icon connect: is it possible? - python

I'm using in Pygtk 2.7 a gtk.Entry. I have set an Icon on this, I would like to know if it's possible to connect the icon to a fonction.
My construction is like this:
def info(self, a, b):
print "INFOS & HELP"
def __init__(self):
window = gtk.window(gtk.WINDOW_TOPLEVEL)
#[...]
self.champ_adr_canal = gtk.Entry()
self.champ_adr_canal.connect("activate", self.download, self.champ_adr_canal)
self.champ_adr_canal.set_text("")
boite_adr.pack_start(self.champ_adr_canal, False, True, 0)
self.champ_adr_canal.set_icon_from_stock(1, gtk.STOCK_DIALOG_QUESTION) # the icon is here
### this line is a pseudo code ####
self.champ_adr_canal.connect("clicked", self.info, "bouton info") # how can I do this?
### ####
self.champ_adr_canal.show()
Thanks!

According to the documentation, you need to make the icon activatable and connect to the icon-press or icon-release signal:
self.champ_adr_canal.set_icon_activatable(1, True)
self.champ_adr_canal.connect("icon-release", self.info)

Related

Restoring QCheckBox with Qsettings

Having QCheckBox wants to save and restore checkstate after closing file.
Tried following but it does not really work!
The code:
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class SecondOrder(QtWidgets.QWidget):
def __init__(self, parent=None):
super(SecondOrder, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 8, QtGui.QFont.Normal, italic=False))
curvaturelabel = QtWidgets.QLabel('Nominal curvature')
stiffnesslabel = QtWidgets.QLabel('Nominal stiffness')
simcurvaturelabel = QtWidgets.QLabel('Simplified nominal curvature')
self.curvaturecheck = QtWidgets.QCheckBox()
self.stiffnesscheck = QtWidgets.QCheckBox()
self.simcurvaturecheck = QtWidgets.QCheckBox()
self.clay = QtWidgets.QVBoxLayout()
self.clay.addWidget(curvaturelabel)
self.clay.addWidget(stiffnesslabel)
self.clay.addWidget(simcurvaturelabel)
self.dlay = QtWidgets.QVBoxLayout()
self.dlay.addWidget(self.curvaturecheck)
self.dlay.addWidget(self.stiffnesscheck)
self.dlay.addWidget(self.simcurvaturecheck)
grid = QtWidgets.QGridLayout(self)
grid.addLayout(self.dlay, 0, 0)
grid.addLayout(self.clay, 0, 1)
Secondorder_Group = QtWidgets.QGroupBox(self)
Secondorder_Group.setTitle("&Second order analysis method")
Secondorder_Group.setLayout(grid)
self.elay = QtWidgets.QHBoxLayout(self)
self.elay.addWidget(Secondorder_Group)
self.elay.setSizeConstraint(self.elay.SetFixedSize)
group = QtWidgets.QButtonGroup(self)
group.addButton(self.curvaturecheck)
group.addButton(self.stiffnesscheck)
group.addButton(self.simcurvaturecheck)
self.readSettings()
self.curvaturecheck.stateChanged.connect(lambda: self.writeSettings())
self.stiffnesscheck.stateChanged.connect(lambda: self.writeSettings())
self.simcurvaturecheck.stateChanged.connect(lambda: self.writeSettings())
def readSettings(self):
settings = QtCore.QSettings('file.ini')
settings.beginGroup("QCheckBox")
self.curvaturecheck.setCheckState(settings.value("A", QtCore.Qt.Checked, bool))
self.stiffnesscheck.setCheckState(settings.value("B", False, bool))
self.simcurvaturecheck.setCheckState(settings.value("C", False, bool))
settings.endGroup()
def writeSettings(self):
settings = QtCore.QSettings('file.ini')
settings.beginGroup("QCheckBox")
settings.setValue("A", self.curvaturecheck.isCheckable())
settings.setValue("B", self.stiffnesscheck.isCheckable())
settings.setValue("C", self.simcurvaturecheck.isCheckable())
settings.endGroup()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = SecondOrder()
w.show()
sys.exit(app.exec_())
Note that following codes are tried, it really saves and restores but it mix multiple checks? wants to be able to check once and restore.
settings.setValue("A", self.curvaturecheck.isChecked())
settings.setValue("B", self.stiffnesscheck.isChecked())
settings.setValue("C", self.simcurvaturecheck.isChecked())
If you are going to save a type T data then you must use the function that uses type T, in your case you save a boolean with isChecked() and you want to use the function setCheckState() that uses a Qt::CheckState type causing the error.
Considering the above there are 2 solutions:
Use bool:
def readSettings(self):
settings = QtCore.QSettings("file.ini")
settings.beginGroup("QCheckBox")
self.curvaturecheck.setChecked(settings.value("A", True, bool))
self.stiffnesscheck.setChecked(settings.value("B", False, bool))
self.simcurvaturecheck.setChecked(settings.value("C", False, bool))
settings.endGroup()
def writeSettings(self):
settings = QtCore.QSettings("file.ini")
settings.beginGroup("QCheckBox")
settings.setValue("A", self.curvaturecheck.isChecked())
settings.setValue("B", self.stiffnesscheck.isChecked())
settings.setValue("C", self.simcurvaturecheck.isChecked())
settings.endGroup()
Use Qt::CheckState
def readSettings(self):
settings = QtCore.QSettings("file.ini")
settings.beginGroup("QCheckBox")
self.curvaturecheck.setCheckState(
settings.value("A", QtCore.Qt.Checked, QtCore.Qt.CheckState)
)
self.stiffnesscheck.setCheckState(
settings.value("B", QtCore.Qt.Unchecked, QtCore.Qt.CheckState)
)
self.simcurvaturecheck.setCheckState(
settings.value("C", QtCore.Qt.Unchecked, QtCore.Qt.CheckState)
)
settings.endGroup()
def writeSettings(self):
settings = QtCore.QSettings("file.ini")
settings.beginGroup("QCheckBox")
settings.setValue("A", self.curvaturecheck.checkState())
settings.setValue("B", self.stiffnesscheck.checkState())
settings.setValue("C", self.simcurvaturecheck.checkState())
settings.endGroup()
It is recommended that you delete the .ini file located in settings.fileName().
On the other hand it is not necessary to use lambda functions, change your code to:
self.curvaturecheck.stateChanged.connect(self.writeSettings)
self.stiffnesscheck.stateChanged.connect(self.writeSettings)
self.simcurvaturecheck.stateChanged.connect(self.writeSettings)
https://doc.qt.io/qt-5/qbuttongroup.html#details
QButtonGroup provides an abstract container into which button widgets can be placed.. It does not provide a visual representation of this container (see QGroupBox for a container widget), but instead manages the states of each of the buttons in the group.
setValue() on every checkbox can switch another.
But the real issue is isCheckable() (means can be checked or not). Probably you want to use isChecked() (value set to true).
EDIT. And you can try to set state by setChecked().
Or if you want to support partially checked use setCheckState() (as you used) with checkState() to get info.

Find the last window created in Maya?

I was wondering if there is any way to find the name of the last window created in Maya, knowing that I can't add any information to the window itself before that... I checked in both the cmds and API but couldn't find anything. Maybe in PyQt but I don't know much about it.
I'm looking for any solution. Thanks
you can work with something like a close callback, save the needed information and restore it again
def restoreLayout(self):
"""
Restore the layout of each widget
"""
settings=self.settings
try:
self.restoreGeometry(settings.value("geometry").toByteArray())
self.restoreState(settings.value("windowState").toByteArray())
size=settings.value('fontSize').toFloat()[0]
self.setFontSize(size)
except:
pass
def saveLayout(self):
"""
Save the layout of each widget
Save the main window id to your data base
"""
settings=self.settings
settings.setValue("geometry", self.saveGeometry())
settings.setValue("windowState", self.saveState())
settings.setValue("fontSize", app.font().pointSize())
def closeEvent(self, event):
QtGui.QMainWindow.closeEvent(self, event)
self.saveLayout()
a simple case/idea to save tha main win_id and a child button_id:
from functools import partial
import json
def close_ui(*args):
win_id = args[0]
if cmds.window(win_id, exists=True):
cmds.deleteUI(win_id, window=True)
with open('dataBase/ui/uidata.json', 'w') as outfile:
json.dump(args, outfile)
win = {}
win["main_win"] = cmds.window()
cmds.columnLayout()
cmds.text( label='closing it' )
win["btn"] = cmds.button( label='Close')
cmds.button(win["btn"],e=True, command=partial(close_ui, win["main_win"], win["btn"]))
cmds.showWindow(win["main_win"])
Here is what I came up with, it's surely not the "cleanest" solution but it works!
# List all the currently opened windows
uisBefore = cmds.lsUI (wnd = True)
# Execute the function which may or may not create a window
func(*args, **kwargs)
# List all the opened windows again
uisAfter = cmds.lsUI (wnd = True)
# Find all the windows that were opened after executing func()
newUIs = [ui for ui in uisAfter if ui not in uisBefore]
If you create a window with the window command, you'll get back the name of the window you just created:
import maya.cmds as cmds
w = cmds.window()
c= cmds.columnLayout()
def who_am_i(*_):
print "window is", w
b = cmds.button('push', c=who_am_i)
cmds.showWindow(w)
If for some reason you don't own the code that creates the window:
existing_windows = set(cmds.lsUI(type = 'window'))
// make your window here
new_windows = list(set(cmds.lsUI(type = 'window') - existing_windows))

gtk.TreeView does not change after changing its gtk.ListStore:

Used: python 2.79, gtk 2.0
Dear python and PyGtk-users
In my program I want to give the opportunity to show searchresults of a great datafile in a gtk.TreeView using the method in the code. In the function that creates the ListStore I also create the csv-file the store is using. Now I can see, that the csv-file has changed after a new search with different keywords, but the TreeView does not, it still keeps the result of the first search, though I clear the store everytime self.search is running. It's really enerving if you need to restart the program for every new search...
I already tried some things, like creating a proper function for the datacreatin for the store, but nothing serves and the truth is that I don't have a lot of ideas...
And everything I found in the internet about this was about autorefreshing of the store with a timer or other topics more profound, seems like everyone instead of me knows how to do this...
Can anyone tell me, what mistake I am making? How do I refresh a TreeView?(as you can see self.search is called by a button...) here the relevant part of the code:
import gtk, csv
class BASE:
#...
#some other funtions, irrelevant for the problem
#...
def search(self, widget, event, data=None):
#...
#all the searchingstuff and the creation of 'inwrite.csv'
#...
with open('/home/emil/Documents/inwrite.csv', 'r') as storefile:
lines = storefile.readlines()
store = gtk.ListStore(str, str, str, str, str, str)
store.clear()
i=0
while i < len(lines):
line = [lines[i]]
csvfile = csv.reader(line, delimiter=',')
for row in csvfile:
temp = (row[0], row[1], row[2], row[3], row[4], row[5])
store.append(temp)
i = i + 1
self.tabview = gtk.TreeView(store)
self.tabview.set_rules_hint(True)
self.tabview.set_reorderable(True)
self.sw.add(self.tabview)
self.tabview.show()
self.create_columns(self.tabview)
def __init__(self):
#...
#creating the Window, entries,...
#...
self.button1 = gtk.Button('Buscar')
self.button1.connect('clicked', self.search, 'button 1')
#...
#packing and showing the whole GUI
#...
def create_columns(self, tabview):
rendererText = gtk.CellRendererText()
rendererText.props.wrap_width = 80
rendererText.props.wrap_mode = gtk.WRAP_WORD
column = gtk.TreeViewColumn('Codigo', rendererText, text=0)
column.set_sort_column_id(0)
self.tabview.append_column(column)
#...
#creating 5 more columns by the same principle
#...
def main(self):
gtk.main()
if __name__=='__main__':
base = BASE()
run = base
run.main()
thanks for your help, tell me if you need more information!
I do not know what is exactly wrong with your program (if you want to know that, you should provide a working minimal example).
Nevertheless, you do not need to manually update the TreeView because the TreeView always shows the content of the ListStore or TreeStore. You also do not have to create the ListStore everytime. You can create it one time and clear and insert the new entries when the event is emitted.
Here is a small example that shows how it works:
#from gi.repository import Gtk # uncomment to use PyGObject
import gtk as Gtk
class TestCase:
def __init__(self):
win = Gtk.Window()
button = Gtk.Button('Show')
button.connect('clicked', self.on_button_clicked)
self.clicked = 0
self.liststore = Gtk.ListStore(int)
self.liststore.append((self.clicked,))
view = Gtk.TreeView(self.liststore)
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn('demo', renderer, text=0)
view.append_column(column)
box = Gtk.HBox()
box.pack_start(button, True, True, 0)
box.pack_start(view, True, True, 0)
win.add(box)
win.connect('delete-event', Gtk.main_quit)
win.show_all()
def on_button_clicked(self, button):
self.clicked += 1
self.liststore.clear()
self.liststore.append((self.clicked,))
if __name__ == "__main__":
TestCase()
Gtk.main()
It also seems that you first create your csv file and read it afterwards. I don't know about the rest of your program but it is probably better to use the data directly and insert it into the ListStore and not read it from the csv file. It might be even possible then to just remove and insert the new entries and not clear the whole ListStore and insert everything again. That would be more efficient with bigger amounts of data.

Gtk.Vte and feed_child: command sent two time

i'm building a tabbed python terminal to manage multiple ssh connection (like superputty or putty manager on windows), so i use feed_child to send command to terminal, but there is a little problem: the command is written 2 time in the terminal, on time before everything.. code is better:
I use this to send the command (in this case for example the command is uptime)
if self.command != "":
self.length_command = len(self.command) + 1
self.hbox.term.feed_child(self.command + "\n", self.length_command)
but in the terminal i get this result
uptime
maurelio#myhost1 ~ $ uptime
19:04:18 up 15 days, 14:32, 2 users, load average: 0,04, 0,07, 0,14
maurelio#myhost1
As you can see, uptime appears in terminal like normal text when i start the program or open a new tab, then appear the prompt and the command is correctly executed. i'd like to get just this:
maurelio#myhost1 ~ $ uptime
19:04:18 up 15 days, 14:32, 2 users, load average: 0,04, 0,07, 0,14
maurelio#myhost1
Any idea?
Update
Here there is a complete code (that should works) :-)
#!/usr/bin/env python
# -*- coding: utf-8; -*-
from gi.repository import Gtk, Vte, GLib
import os
class Terminal(Vte.Terminal):
"""Just create a standard terminal with some configuration
"""
def __init__(self):
super(Terminal, self).__init__()
self.configure_terminal()
def configure_terminal(self):
self.set_audible_bell(False)
self.set_visible_bell(False)
self.set_sensitive(True)
self.fork_command_full(Vte.PtyFlags.DEFAULT, os.environ['HOME'], ["/bin/bash"],
[], GLib.SpawnFlags.DO_NOT_REAP_CHILD, None, None)
class Window(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Terminal")
self.box = Gtk.Box(spacing=6)
self.add(self.box)
self.term = Terminal()
self.box.pack_start(self.term, True, True, 0)
self.term.set_audible_bell(False)
self.term.set_visible_bell(False)
self.term.set_sensitive(True)
self.term.fork_command_full(Vte.PtyFlags.DEFAULT, os.environ['HOME'], ["/bin/bash"],
[], GLib.SpawnFlags.DO_NOT_REAP_CHILD, None, None)
self.command = 'uptime'
self.length_command = len(self.command) + 1
self.term.feed_child(self.command + "\n", self.length_command)
self.term.connect("child-exited", Gtk.main_quit)
win = Window()
win.connect("delete-event", Gtk.main_quit)
win.show_all()
Gtk.main()
If you run this, you will see the problem.
Thanks.
You forgot to add the Vte terminal to a ScrolledWindow first:
Gtk.Window.__init__(self, title="Terminal")
self.set_default_size(600, 300)
self.box = Gtk.Box(spacing=6)
self.add(self.box)
self.term = Terminal()
self.sw = Gtk.ScrolledWindow()
self.sw.add(self.term)
self.box.pack_start(self.sw, True, True, 0)

How change Gtk 3 code to pygtk 2.0

How can I change this code from Gtk 3 to pygtk 2.0?
https://github.com/sebp/PyGObject-Tutorial/blob/master/examples/cellrenderertoggle_example.py
I have this part.
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk
class CellRendererToggle:
def cell_toggled(self, widget, path):
self.liststore[path][1] = not self.liststore[path][1]
def __init__(self):
window = gtk.Window()
window.set_default_size(200, 200)
self.liststore = gtk.ListStore(str, bool, bool)
self.liststore.append(["Debian", False, False])
self.liststore.append(["OpenSuse", False, False])
self.liststore.append(["Fedora", False, False])
treeview = gtk.TreeView(model=self.liststore)
cellrenderer_text = gtk.CellRendererText()
column_text = gtk.TreeViewColumn("Text", cellrenderer_text, text=0)
treeview.append_column(column_text)
cellrenderer_toggle = gtk.CellRendererToggle()
cellrenderer_toggle.connect("toggled", self.cell_toggled)
column_toggle = gtk.TreeViewColumn("Toggle", cellrenderer_toggle, active=1)
treeview.append_column(column_toggle)
renderer_radio = gtk.CellRendererToggle()
renderer_radio.set_radio(True)
renderer_radio.connect("toggled", self.cell_radio_toggled)
column_radio = gtk.TreeViewColumn("Radio", renderer_radio, active=2)
treeview.append_column(column_radio)
window.connect("destroy", lambda w: gtk.main_quit())
window.add(treeview)
window.show_all()
CellRendererToggle()
gtk.main()
I haven't done that much with pygtk, but:
Easiest thing is probably to try running the code, and seeing where you get tracebacks. Find one, fix one, find one, fix one.
There may well be a porting guide from 2.x to 3.x, but I doubt there's one for 3.x to 2.x. However, looking at a 2.x to 3.x porting guide might help a little.

Categories