My company is using Python 2.6 (yuck, I know, but it's my constraint). I need to make a little GUI that involves a ComboBox. I chose Tix, because that's what I have--not allowed to grab anything else.
Anyway, I'd like to set the label that the ComboBox has to the top side. According to the documentation at http://tix.sourceforge.net/dist/current/man/html/TixCmd/tixComboBox.htm, if I use "labelside" in the ComboBox constructor as a parameter, it should move the label to the top, like I want.
Unfortunately, when I do this, it gives me a strange error:
_tkinter.TclError: cannot assigned to static variable "-labelside"
CONTEXT: this is within a Python class that inherits from Tix.Frame. The first code example works perfectly, the other does not.
My constructor (not including 'labelside') looks like this:
combobox = Tix.ComboBox(self,
label="Available files: ",
selectmode='immediate',
dropdown=0,
editable=0,
variable=selectedfile,
options='listbox.height 5')
It works perfectly, as expected. I get a nice ComboBox in my window. The label is the left side, however--not what I want.
So, I try this:
combobox = Tix.ComboBox(self,
label="Available files: ",
labelside='top',
selectmode='immediate',
dropdown=0,
editable=0,
variable=selectedfile,
options='listbox.height 5')
That's when it gives me the error. I've scrounged the internet for answers, but have found only users who have the same unanswered question: why is it happening? It would appear that I'm following the documentation correctly.
I also tried substituting Tix.TOP for top, and it gave me the same error.
Any help or ideas would be greatly appreciated!
Related
I writing gtk interface with python code. the problem is:
init entry widget by gtkbuilder:
self.some_entry = self.builder.get_object('SomeEntry')
Define signal by typing button, after then must changed entry color:
def on_SomeButton_clicked(self, widget):
self.some_entry.modify_bg(Gtk.StateType.NORMAL,Gdk.Color(20000,10000,10000))
but it doesn't work, such 'modify_base'. And I don't know why. Help please.
Sorry for my English(
EDIT2:
Turns out it was an entry box giving the problem which is another issue in and of itself because the background is not the property you need to modify but the BASE color property which can typically be set using:
self.entry.override_background_color(Gtk.StateType.Normal, Gdk.RGBA(0.0, 1.0, 0.0, 1.0))
However for OP it was not working so a CSS option was explored, listed at: https://mail.gnome.org/archives/gtk-app-devel-list/2005-November/msg00236.html
EDIT:
So working with PyGtk3 I was able to get a button changing color using you line of code:
self.button.modify_bg(Gtk.StateType.Normal, Gdk.Color(20000, 10000, 10000))
It was grey on initialization and dark red after the code ran. The only thing I could think of is make sure that the object you are trying to modify is actually in a NORMAL state after you run the code and make sure the signal you think is triggering is actually triggering.
==============
Original post:
Without having the full code here there are a few things that could be causing this. I just threw together a test program in Python based off of: http://pygtk.org/pygtk2tutorial/examples/helloworld.py
When I set the Gtk State for the modify_bg I had to use:
gtk.STATE_NORMAL
Not sure if that is due to a different version of Gtk or what though.
Then when I went to use Gdk I had to refer to it as:
gtk.gdk
The line that I ended up with to change the button color was:
self.button.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color(20000, 10000, 10000))
Hopefully that works out, in order to get any more detailed though we would definitely need more code and to know what kind of errors you are getting.
CSS works, code below:
style_provider = Gtk.CssProvider()
css = open('style.css', 'rb')
css_data = css.read()
css.close()
style_provider.load_from_data(css_data)
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
style_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION)
With line
"widgetname".get_style_context().add_class("colorize")
"widgetname" has been colorized.
CSS code:
.colorize {
background: rgba(200,50,50,0.3);
}
I'm reading Programming Python by Mark Lutz, and I came across this bit of code that I don't get.
buttons = []
def onpress(i):
global state
state = i
for btn in buttons:
btn.deselect()
buttons[i].select()
I get what it's doing, but I don't get where these select and deselect methods are coming from. I've never seen these list methods before (I and the book are using Python 3). Are these builtin methods? And what do they do? I tried using my Google-fu to figure it out, but to no avail.
http://www.java2s.com/Tutorial/Python/0360__Tkinker/Deselectforradiobuttonssimplysetsthebuttonsassociatedvaluetoanullstring.htm
So a quick google, if you are doing this it means you are most likely using tkinter in which case you have missing relevant code somewhere.
Those methods .deselect() and .select() are actually tkinter Radiobuttons() methods. If you're tutorial reverences tkinter. "from tkinter import *" will import those class's. If not i have no idea why its being taken out of context.
But what this code does is, it takes 'i', which is a button you click, then it sets 'state' to 'i', making 'state' 'global' over writing the last 'state', then it deselects all buttons, and selects 'i' which is your new choice. In effect this means you'll only ever select 1 button
If you wonder why state is an empty string, its because an empty string is the first button in tkinter. When you pass a new string in, it gives the new item being something like "I001" or something.
This is where the error is found:
global backbuttonimg
backbuttonimg = PhotoImage(file="backbutton.gif")
C6 = tkinter.Button(W_CheckDates, image=backbuttonimg, command = CheckDatesBack)
C6.pack()
I don't understand why this isn't working. I have another image in my program here:
def Login():
global W_Menu
W_Menu = Tk()
W_Menu.geometry('160x310+600+200')
W_Menu.title("NSS DB")
A0 = Canvas(W_Menu, width='160', height='160')
A0.pack()
global img
img = PhotoImage(file="nsslogo.gif")
A0.create_image(80,80, image=img)
I also get a similar error when I try to call the above definition after it has already been initially called (for example when my program logs out) so I have readjusted so the window simply deiconifies instead of calling it again, and I do not get the error again. However I am confused as to why I get an error with the former section of code now, as the button simply does not show up whether it is called for the first time or not. Sorry if this is a bit vague, please ask if I have not explained in enough detail. Thanks in advance.
P.S. I have looked in other threads with similar problems but none apply to me.
Ok so you say that the login function works once, then it can't work again. Here the problem can be solved using tk.Toplevel() instead of tk.Tk() see: why python photoimages don't exist? and tkinter.TclError: image "pyimage3" doesn't exist
These threads mention how you can't have two instances of Tk() running simultaneously, you have to use Toplevel() instead.
Why did these threads not apply to you (i think they do...)? But just a tip, if you state that they don't apply to you, then give reasons why, it helps make your question clearer. Also, add the full traceback when your question is about a particular error.
Hope this helps a bit.
Adding this for anyone who has tried the above with no success. If you have an erroneous path when running the script in some environments the path to the file is retained. I commented out everything from where I first use PhotoImage up to the window mainloop, run the script, close resulting gui, uncomment the code, run, and it shows the image as expected.
You can add a master parameter
backbuttonimg = PhotoImage(file="backbutton.gif",master=W_Menu)
Here Cledia
I am also facing this error.
And when I use Toplevel instead of To, it is working well
I suggest you to use TopleToplevel
Use tk.Toplevel() instead of tk.Tk() So its will work because the python coding library tkinter it doesnt make any sens if you make two windows working sametime with the tk.Tk() so you can use the toplevel() to open multiwindows in the same time !!
Hope it's Helpful
This is related to another question I found here that seems to be inactive for a few months, so I think it's worth asking again.
I have created a simple QDialog that has a QTextEdit and a QPushButton. This pops up in my application when a user right-clicks and selects the option to "add comments". I want them to be able to write free-form text and I'll just save whatever they write as a long string with no concern for new lines, etc.
When the user clicks the button, it executes code like this:
self.connect(accept_button,QtCore.SIGNAL('clicked()'),lambda arg=str(view_textedit.toPlainText()): self.updateGroupComments(arg))
def updateGroupComments(self,new_comment_str):
print "Updating user comment to have new string: " + new_comment_str
self.group_entry.list_of_user_comments[self.currentFrameCounter] = new_comment_str
This is not detecting the TextEdit text that is visible (it only detects whatever the text edit text is set to when it is created). How do I make a simple command that returns the currently visible text from a QTextEdit. Again, the function
toPlainText()
is not working correctly... it doesn't find the currently visible text, only whatever text was on screen before changes or additions started being made by the user.
If this can't be done without subclassing and appealing to cursor positions, it makes the whole thing seem worthless... so please keep suggestions only to those implemented without subclassing or manipulating cursors. It should be really simple and straightforward to just return all currently visible text... what am I missing?
Objects that are being bound to default arguments are evaluated at the definition time. The function is working correctly, it returns whatever was in the text field when it was executed. Your code simply calls it at the wrong moment. If you want to use lambda, then do:
self.connect(
accept_button, QtCore.SIGNAL('clicked()'),
lambda: self.updateGroupComments(str(view_textedit.toPlainText()))
)
Or make view_textedit an instance attribute instead, and do simply
self.connect(
accept_button, QtCore.SIGNAL('clicked()'), self.updateGroupComments
)
And change updateGroupComments to call self.view_textedit.toPlainText instead of taking an argument.
BTW, this is not PyQt specific, this is how Python works in general.
To illustrate my last comment, that lambda can very well be replaced with:
def slot():
self.updateGroupComments(str(view_textedit.toPlainText()))
self.connect(accept_button, QtCore.SIGNAL('clicked()'), slot)
I'm writing an app that doesn't have a main window (it runs inside a Python interpreter in another app), and I thought I had a good solution for getting Tkinter to cooperate--I made the Tkinter.Tk class into a Borg.
class RootWindow(Tk):
""" Invisible window that serves as the default parent
of all others.
"""
groupDict = {}
def __init__(self):
self.__dict__ = self.groupDict
if self.__dict__ == {}: # first instance
Tk.__init__(self)
self.withdraw()
Then I have my Windows, which are subclassed from Tkinter.Toplevel, default to parent=RootWindow(). The result should be that I can create any number of Windows and they'll use the same root.
It works once fine for the first Window, but after that things get all messed up. :(
see pic
What am I doing wrong? Is this even a feasible solution?
Thanks
EDIT: I should add that even though there's other stuff running in the picture, the problem can be duplicated just by using RootWindow as the parent of a Tkinter.Toplevel.
EDIT: I overrode Window.mainloop so everything uses the RootWindow event loop.
def mainloop(self):
self.master.wait_window(self)
Then I create each visible window like this:
test = Window()
test.mainloop()
It seems to work because the windows do show up, but their contents are packed in an odd way that's hard to describe. It alternates between no contents at all and having everything squished horizontally and expanded vertically.
One problem appears to be that you are forgetting to start the event loop. Or, based on further edits of your question, you may be starting more than one main loop. You need exactly one main loop that is run from the root window.
Tkinter certainly allows an arbitrary number of top level windows, but your question doesn't appear to have enough details to show what is wrong unless my first guess is correct.