How do I port MultiCheckComboBox to PySide? - python

I want the items in a combobox to be checkable. I have found a way to do this here.
This specific example uses PyQt and since I use PySide, it needs some modifications to work.
The first error I get is about QStringList which I replaced with [].
Then I get the following error:
Traceback (most recent call last):
File "MultiCheckComboBox.py", line 401, in data
if not value.isValid():
AttributeError: 'NoneType' object has no attribute 'isValid'
I am not sure what needs to be changed to fix the above error.

PyQt4 (by default) returns some values as instances of QVariant (although it can be configured to return a native Python type). PySide however, always converts to native Python types.
Your code is assuming that PyQt4 will be using QVariant. That line of code assumes value is a QVariant. You will need to change it to:
if value is not None:
in this case, however this is unlikely to be the only instance of a QVariant in this code and the modification you need to make to those will be dependent on the QVariant function that the code is trying to call.

Related

'int' object has no attribute 'set'

I'm working on a project where you click a button and it changes an int and writes it to the screen. My issues is that when I try to set a new value to the int it comes back with an AttributeError.
def busy():
unit_status.set(7)
Everything else is working except for that one line, and I can't for the life of me figure out why.
While this thread is a bit old, I dont think LouieC's response fully answered the OP's concern.
LouieC mentions that set is a built-in class, which is correct. But it is likely Warrior's Path was looking for the values, since he wanted to write them to the screen.
IF he didnt ask, then I am asking based upon an observation in the following code, adapted from the geeksforgeeks.org explanation. My point is addressed in the comments, particularly at the end.
Notice when LouieC's technique is applied it seems to incorrectly overwrite the entirety of IntVar.
# importing tkinter module
from tkinter import *
# creating Tk() variable
# required by Tkinter classes
master = Tk()
# Tkinter variables
# initialization using constructor
intvar = IntVar(master, value = 25, name ="2")
strvar = StringVar(master, "Hello !")
boolvar = BooleanVar(master, True)
doublevar = DoubleVar(master, 10.25)
print(intvar) # This prints the NAME, not the value.... the name is auto-assigned by python
print(strvar) # if not explicity declared...
print(boolvar)
print(doublevar)
print(intvar.get()) # This prints the VALUE, not the name....
print(strvar.get())
print(boolvar.get())
print(doublevar.get())
# But now watch what happens...
intvar = 1
print(intvar)
print(intvar.get())
# What's interesting here is... print(intvar.get()) worked at line 20...
and yet now it generates the following error
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-16-61984dfda0fb> in <module>
26 intvar = 1
27 print(intvar)
---> 28 print(intvar.get())
AttributeError: 'int' object has no attribute 'get'
If one runs a type test, in the first case, around line 20:
print(type(intvar))
One will get:
<class 'tkinter.IntVar'>
But if one runs the same type test after LouieC's reassignment, one will get:
<class 'int'>
That's why I said the reassignment doesnt work right.
The OP's question still seems to be open.
This is not how you reassign a variable of type integer; you want:
unit_status = 7
set is a built-in class in Python; official docs here
A set object is an unordered collection of distinct hashable objects. Common uses include membership testing, removing duplicates from a sequence, and computing mathematical operations such as intersection, union, difference, and symmetric difference. (For other containers see the built-in dict, list, and tuple classes, and the collections module.)

HarfBuzz language_from_string Python introspection method doesn't accept str

I'm just getting started with HarfBuzz, and have switched to using the GObject Introspection interface to explore its API. Everything has been easy so far, but I'm a bit confused with language_from_string, which has the following docstring:
language_from_string(str:list) -> HarfBuzz.language_t
i.e. in IPython, I do:
from gi.repository import HarfBuzz
?HarfBuzz.language_from_string
in vanilla Python, you can replace the last line with: print(HarfBuzz.language_from_string.__doc__) (or similar)
if I call this method with a string, e.g:
HarfBuzz.language_from_string('en')
I get
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Item 0: Must be number, not str
back, while if I convert to a list of code points first:
en = HarfBuzz.language_from_string(list(map(ord, 'en')))
the error goes away, and I get something useful back. e.g. I can do:
HarfBuzz.language_to_string(en)
and I get the expected en back, in a string.
HarfBuzz Issue #91 is about this method, but doesn't seem to be relevant.
You have to call it like HarfBuzz.language_from_string(b'en') (string but prefixed with b) in python3 as strings are not just sequence of bytes anymore in py3 unlike py2.
Do you know any gi API that gets an actual python representation of string in python3? If so let me know otherwise this is expected from HarfBuzz side.

Python Error Handling

I was trying to convert the list to a set, with the following code:
set1=set(list1)
the code was running fine, but all on a sudden started to give the following error,
set1=set(list1)
TypeError: unhashable type: 'list'
please let me know how may I resolve.
And sometimes some good running program gives error all on a sudden with no parameter changed, how may I debug it?
Your error suggests that your list contains a list. Lists are mutable and thus can't be hashed for use in a set or a dictionary. One work-around is to convert your list into a tuple using tuple(some_list), but if they're heavily nested, it becomes more complex.
Your list contains another list:
>>> set([['contained list'], 1, 2])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
Sets can only contain items that are hashable; any standard type that cannot be mutated is hashable, but a list is not (it can be mutated). By contrast, a tuple is not mutable and can be stored in a set.
Bugs happen, even in code that has been running fine for a while. Debug it with print statements, or better still, by using a debugger like the pdb.
If your bug only appears intermittently, use a try/except block to catch the error, then print out information or use a debugger to figure out what is going on:
try:
set1=set(list1)
except TypeError:
print 'list1 not hashable? contents: %r' % list1
# optionally: import pdb; pdb.set_trace()
raise

added typelib via makepy for AutoCAD, now win32com not working for AutoCAD

I have been running win32com to access AutoCAD for quite some time without issue. I learned that applying the makepy utility could create a more user friendly experience at the interactive prompt, so I ran it and added the "AutoCAD 2006 Type Library". Now, some common attributes that I used to access are no longer available. Consider the code:
acad = win32com.client("AutoCAD.Application")
doc = acad.Documents.Open('mydoc.dwg')
ms = doc.ModelSpace
count = ms.Count #counts all entities in dwg
for i in range(count):
item = ms.Item(i)
if 'block' in item.ObjectName.lower():
print item.Name
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "C:\Python27\lib\site-packages\win32com\client\__init__.py", line 462, in
__getattr__ raise AttributeError("'%s' object has no attribute '%s'"
(repr(self),attr))
AttributeError: '<win32com.gen_py.AutoCAD 2006 Type Library.IAcadEntity instance
at 0x34894552>' object has no attribute 'Name'
Name has always been an accessible attribute of a block until I ran makepy. I've tried reinstalling Python for windows to see if that would reset it, but it didn't work.
Does makepy create another file upon implementation that I need to remove?
So many of my scripts depend upon the Name attribute. Any suggestions or help you could offer would be greatly appreciated.
The main reason for this attribute error is because your COM-server has shifted from late-binding (dynamic) to early binding (static).
In Late Binding, whenever a method is called, the object is queried for the method and if it succeeds, then the call can be made.
In Early Binding, the information of the object model is determined in advance from type information supplied by the object call. Early binding makes use of MakePy. Also, early binding is case sensitive.
There are two ways to fix this issue:
Use the dynamic module to force your code to work in a late-bound oriented way. Example use:
win32com.client.dynamic.Dispatch() instead of win32com.client.Dispatch()
Use camelcase sensitive keywords for the early bound oriented way. Example use:
excel.Visible() instead of excel.VISIBLE() or excel.visible()
So try using dynamic.Dispatch or case-sensitive variable names.
I encounter a similar problem when I run win32com to access DELMIA. I find out that delmia has lots of com stuff as .tlb files. When I type:
from win32com.client.gencache import EnsureDispatch
EnsureDispatch('DELMIA.Application')
Python will automatically generate some stuff in win32com\gen_py directory, same as example of Word or Excel. But, the difference is that the generated stuff is from only one .tlb file of delmia. If I access some variable in the `.tlb, it's ok:
docs = delmia.Documents
If I access some variable in other .tlb, I get a similar error:
pdoc = docs.Add('Process')
Python says that:
... object has no attribute ...
So I delete all files in the win32com\gen_py directory but keep gen_py directory, and it is ok now.

Preventing invoking C types from Python

What's the correct way to prevent invoking (creating an instance of) a C type from Python?
I've considered providing a tp_init that raises an exception, but as I understand it that would still allow __new__ to be called directly on the type.
A C function returns instances of this type -- that's the only way instances of this type are intended to be created.
Edit: My intention is that users of my type will get an exception if they accidentally use it wrongly. The C code is such that calling a function on an object incorrectly created from Python would crash. I realise this is unusual: all of my C extension types so far have worked nicely when instantiated from Python. My question is whether there is a usual way to provide this restriction.
Simple: leave the tp_new slot of the type empty.
>>> Foo()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: cannot create 'foo.Foo' instances
>>> Foo.__new__(Foo)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object.__new__(foo.Foo) is not safe, use foo.Foo.__new__()
If you inherit from a type other than the base object type, you will have to set tp_new to NULL after calling PyType_Ready().
Don't prevent them from doing it. "We're all consenting adults here."
Nobody is going to do it unless they have a reason, and if they have such a reason then you shouldn't stop them just because you didn't anticipate every possible use of your type.
There is a fantastically bulletproof way. Let people create the object, and have Python crash. That should stop them doing it pretty efficiently. ;)
Also you can underscore the class name, to indicate that it should be internal. (At least, I assume you can create underscored classnames from C too, I haven't actually ever done it.)
"The type is a return type of another C function - that's the only way instances of this type are intended to be created" -- that's rather confusing. I think you mean "A C function returns instances of this type -- that's the only way etc etc".
In your documentation, warn the caller clearly against invoking the type. Don't export the type from your C extension. You can't do much about somebody who introspects the returned instances but so what? It's their data/machine/job at risk, not yours.
[Update (I hate the UI for comments!)]
James: "type ...just only created from C": again you are confusing the type and its instances. The type is created statically in C. Your C code contains the type and also a factory function that users are intended to call to obtain instances of the type. For some reason that you don't explain, if users obtain an instance by calling the type directly, subsequent instance.method() calls will crash (I presume that's what you mean by "calling functions on the object". Call me crazy, but isn't that a bug that you should fix?
Re "don't export": try "don't expose".
In your C code, you will have something like this where you list out all the APIs that your module is providing, both types and functions:
static struct PyMethodDef public_functions[] = {
{"EvilType", (PyCFunction) py_EvilType, ......},
/* omit above line and punters can't call it directly from Python */
{"make_evil", (PyCFunction) py_make_evil, ......},
......,
};
module = Py_InitModule4("mymodule", public_functions, module_doc, ...

Categories