Binding MouseClick to widget of an instance - python

I have an instance of a ttkcalendar object, "cal". When I bind a button click to cal, the function called only executes if I click in the corners of the ttcalendar frame; when I click on the actual calendar area, while the ttkcalendar functions execute, my bind does not.
This code runs when I click Frame corners
# Calendar Frame
self.cal=Calendar(LeftFrame)
self.cal.pack(side=TOP)
self.cal.bind("<Button-1>",self.clicked)
I thought that if I try to bind to the canvas object of the calendar it would work. However this code returns AttributeError: Calendar instance has no attribute canvas.
# Calendar Frame
self.cal=Calendar(LeftFrame)
self.cal.pack(side=TOP)
self.cal.canvas.bind("<Button-1>",self.clicked)
As I said, internal ttkcalendar binds work fine for switching date shown. Any insights? Thanks

The error message should be pretty clear. If python is telling you "AttributeError: Calendar instance has no attribute canvas", you must assume that to be true.
Looking at the source code of the Calendar class, I don't see any canvas attribute. Just like the error is telling you, you're trying to access an attribute that doesn't exist.
The Calendar class does have an attribute named _canvas, maybe you can try using that instead. Though, that leading underscore denotes that it is intended as a private attribute and may go away in future revisions of the code.

Related

AttributeError: 'function' object has no attribute 'geometry'

I've created a toplevel window in my Tkinter program. However it just doesn't seem to get the geometry part.
Some of the code:
def calreco():
calreco_screen = Toplevel(cc)
calreco_screen.title("Your Recommended Calorie Intake Is")
calreco.geometry("400x400")
You are initiated and called a different/unknown object.
calreco.geometry("400x400")
Instead, Try
calreco_screen.geometry("400x400")
This could solve your issue.

List/inspect the instance variables (self.xxx) while using pudb

I am trying to debug a python application using pudb, everything is fine and good except that it's not displaying the instance variables (which we access with self.xxx). It just displays 1 variable called self. And it's of the original class type.
Even if I tell it to show after calling str(self), it still only displays the object information.
If you see the code has created many variables like self.parser, self.groups and I am not able to view/inspect any of them.
Is there a way to view all the instance variables of the current class while debugging using pudb?
This is the expected behaviour, and has nothing to do with your debugger: you only have one name, self.
To see its contents you can use dir(self).
See inspect complex variable in python debugger, like pudb
The short way: Highlight the variable and press backslash \ to toggle between the "Expanded" view of a variable in the variable inspection panel.
In this case we would just highlight self, and press \, which is just the Python variable representing the instance of the class.
Alternatively, press ENTER to open the "Variable Inspection Options" menu where at the bottom you can see the "Expanded" option.

Incorrect stack data in Wing IDE with Tkinter?

I am using Wing to write and debug a Tkinter GUI. I am finding that the Stack Data View doesn't seem to match the actual attributes of my widgets. Take this code for example:
import Tkinter
import ttk
root = Tkinter.Tk()
checkbutton = ttk.Checkbutton(root, text="Test Check Button")
print checkbutton.text
This gives me an attribute error at the last line. However, when I look at the stack, there is clearly an attribute called 'text' with the value that I'm looking for:
Anyone know what's going on?
I'm using:
Wing version: Wing IDE Pro 5.1.3-1 (rev 33002)
Tkinter version: '$Revision: 81008 $'
Python version: 2.7.10
I posted this to the Wing email list, and I got the following response from the developers:
It looks like a ttk.Checkbutton defines keys() and __getitem__()
methods to exposes tk attributes via checkbutton[<name>]. Because
of the keys() and __getitem__(), Wing is displaying the instance
as if it were a dictionary, with the keys and values interspersed with
the attributes. Wing does this because often you want to view an
object that defines keys() and __getitem__() as if it were a
dictionary, but I agree that it's confusing in this instance.
We'll try to improve this in a future release.
What you are calling attributes are not object attributes. Widgets use an internal system for managing the widget options. .text is not an attribute, which is why you get the error. To reference the configuration use .cget(...) to get the value and .configure(...) to change the value.

PyQt Runtime Error of QTreeWidgetItem

I'm trying to avoid the well-known PyQt Runtime Error when the underlying C/C++ object is deleted:
http://www.riverbankcomputing.com/pipermail/pyqt/2009-April/022809.html
PyQt4 - "RuntimeError: underlying C/C object has been deleted"
PyQt4 nested classes - "RuntimeError: underlying C/C++ object has been deleted"
PyQt: RuntimeError: wrapped C/C++ object has been deleted
Every one of my subclasses calls the super() method and therefore the base classes are properly constructed.
Still, I get this error and am wondering if it is due to the fact that I'm adding a QComboBox widget to a QTreeWidgetItem (using the setItemWidget() method of a QTreeWidget) but I cannot set the parent as the QTreeWidgetItem that contains it. When I try, I get the following error:
TypeError: QComboBox(QWidget parent=None): argument 1 has unexpected type 'QTreeWidgetItem'
Of course, I can either omit the parent in the constructor or pass the QTreeWidget as the parent, but I think I need to reference the correct parent.
I have subclassed the QComboBox and in my subclass it runs some basic operations on the QTreeWidget, but as soon as I enter the methods of my subclassed QComboBox, the underlying C object for the parent QTreeWidgetItem containing the QComboBox is deleted (which is why I'm thinking its something to do with setting the parent of the QComboBox).
I understand 9 times out of 10 the runtime error is due to not constructing the base class. But with that ruled out, how else can the error occur? Could it be due to not referencing the correct parent?
EDIT
I'm using the QComboBox to signal when a new combobox selection was made. Upon a new selection, it adds that selected value to a PyXB XML node. Interestingly, this issue only occurs if I append the value to the PyXB class binding storing the information permanently in an XML file. In otherwords, if that part of the code doesn't run I dont get the error - its only when the code runs the PyXB operation for appending a value to an XML node binding...
I usually avoid that kind of errors keeping a reference on my class to all the objects susceptible of being deleted like your QComboBox so try something like self.comboBoxHolder = QComboBox(...) when you create it.

Need help with Classes in Python

I'm making a program that imports a custom widget that is a class (it inherits from the Tkinter Frame widget). It all works great until I get to binding. To reduce confusion we'll call the main application app, the module it's importing the widget from lib, and the widget that's being imported into app will be called cwid.
Basically I need to somehow reference a function in app, so that it may be bound to my widget in lib.
The function I'm trying to bind a widget within cwid to is element_click (The function element_click is in app.):
lambda event: element_click(event, elementinfo[3])
So the binding would look something like this in lib (element is a canvas widget within cwid)
element.bind('<ButtonRelease-1>', lambda event: element_click(event, elementinfo[3]))
The above line wont work however seeing as element_click is in app. So I tried a work around which doesn't seem to be working.
import app
loc = app.EOG
element.bind('<ButtonRelease-1>', lambda event: loc.element_click( event, elementinfo[3]))
When I try the above I get the following error:
TypeError: unbound method element_click() must be called with EOG instance as first argument (got Event instance instead)
EOG is a class in app which contains element_click.
Also, all of the above bits of code are snippets.
EDIT:
Tried loc = app.EOG(), and go the following error:
AttributeError: EOG instance has no attribute '__nonzero__'
I think you just want:
loc = app.EOG()
Then, loc is an instance of EOG, and loc.element_click is a bound method, so it works as intended.

Categories