Pygtk object uninitialized - python

Hi during the creation of multiple objects in pygtk application, calling some of these object return that they are uninitialised when passing there contents to signals (noting the value are showen correctly in the application)
sections = config.sections()
for section in sections:
box= gtk.Table (3,len(config.options(section)),False)
box.set_col_spacings(2)
box.set_row_spacings(2)
box.show()
label = gtk.Label(section)
label.show()
notebook.append_page (box,label)
for i,option in enumerate(config.options(section)):
optionlabel = gtk.Label(option)
optionvalue = gtk.Entry ()
optionvalue.set_text(config.get(section,option))
--> optionvalue.connect("activate", enter_callback,optionvalue, label, optionlabel)
box.attach(optionlabel,0,1,i,i+1,xoptions=gtk.SHRINK|gtk.FILL,yoptions=gtk.SHRINK)
box.attach(optionvalue,1,2,i,i+1,yoptions=gtk.SHRINK)
box.show_all()
at first I thought that the variables are not in scope but they were ( I've tested several objects and found them working the last 3 lines
Linuxcnc ini.py:70: GtkWarning: IA__gtk_entry_get_text: assertion "GTK_IS_ENTRY (entry) failed
print (widget.get_text())
None
<gtk.Label object at 0x9f44a54 (uninitialized at 0x0)>
<gtk.Label object at 0x9f44c0c (uninitialized at 0x0)>
0
<gtk.Label object at 0x9f4c8ec (GtkLabel at 0xa1a3350)>
<gtk.Label object at 0x9f4dc0c (GtkLabel at 0xa1a3450)>

For this one I think you may need to look in the Gtk system library itself.
(The source code that is used to produce ".so", ".dll" or ".dylib" file, that has the routines that your Python program is accessing).
You can look a the contents of such binary files with commands like "strings", "nm", and "objdump".
But based the nature of the error, it looks like the fix will be done in the source code of the library itself, not the Python program.
Sorry I cannot give more detail than that.

Related

How to write a custom debugging helper for nlohmann::basic_json?

I am faced with the task of writing a simple debug helper for Qt Creator 4.13.1 / Qt 5.12.5 / MSVC 2017 compiler for the C++ JSON implementation nlohmann::basic_json (https://github.com/nlohmann/json).
An object of nlohmann::basic_json can contain the contents of a single JSON data type (null, boolean, number, string, array, object) at a time.
There's a dump() member function which can be used to output the current content formatted as a std::string regardless of the current data type. I always want to use this function.
What I've done so far:
I've looked at https://doc.qt.io/qtcreator/creator-debugging-helpers.html, as well as at the given example files (qttypes.py, stdtypes.py...).
I made a copy of the file personaltypes.py and told Qt Creator about its existence at
Tools / Options / Debugger / Locals & Expressions / Extra Debugging Helpers
The following code works and displays a "Hello World" in the debugger window for nlohmann::basic_json objects.
import dumper
def qdump__nlohmann__basic_json(d, value):
d.putNumChild(0)
d.putValue("Hello World")
Unfortunately, despite the documentation, I have no idea how to proceed from here on.
I still have absolutely no clue how to correctly call basic_json's dump() function with the dumper from Python (e.g. with d.putCallItem ?).
I also have no starting point how to format the returned std::string so that it is finally displayed in the debugger window.
I imagined something like this, but it doesn't work.
d.putValue("data")
d.putNumChild(1)
d.putCallItem('dump', '#std::string', value, 'dump')
I hope someone can give me a little clue so that I can continue thinking in the right direction.
For example, can I call qdump__std__string from stdtypes.py myself to interpret the std::string?

How to create and use objects from the Inventor COM API in python (pywin32)

I'm attempting to use Autodesk Inventor's COM API to create a python script that will generate PDFs of a selection on Inventor Drawings, these PDFs will then be processed in particular ways that aren't important to my question. I'm using pywin32 to access the COM API, but I'm not particularly familiar with how COM APIs are used, and the pywin32 module.
This is the extent of the documentation for Inventor's API that I have been able to find (diagram of API Object Model Reference Document), and I have not been able to find documentation for the individual objects listed. As such, I'm basing my understanding of the use of these objects on what I can find from examples online (all in VB or iLogic - Inventor's own simple built-in language).
A big issue I'm coming up against is in creating the objects I'd like to use. Simplified example below:
from win32com.client import *
# user chooses file paths for open and save here...
drawing_filepath = ""
# Open Inventor application, and set visible (so I can tell it's opened for now)
app = Dispatch('Inventor.Application')
app.Visible = True
# Open the file to be saved as a pdf (returns a Document object)
app.Documents.Open(drawing_filepath)
# Cast the opened Document object to a DrawingDocument object (it is guaranteed to be a drawing)
drawing = CastTo(app.ActiveDocument, "DrawingDocument")
# Create and setup a print manager (so can use "Adobe PDF" printer to convert the drawings to PDF)
print_manager = ??? # How can I create this object
# I've tried:
# print_manager = Dispatch("Inventor.Application.Documents.DrawingDocument.DrawingPrintManager") #"Invalid class string"
# print_manager = drawing.DrawingPrintManager() #"object has no attribute 'DrawingPrintManger'
# print_manager = drawing.DrawingPrintManager # same as above
# print_manager = drawing.PrintManger # worked in the end
print_manager.Printer = "Adobe PDF"
print_manager.NumberOfCopies = 1
print_manager.ScaleMode = print_manager.PrintScaleModeEnum.kPrintFullScale
print_manager.PaperSize = print_manager.PrintSizeEnum.kPaperSizeA3
# Print PDF
print_manager.SubmitPrint()
So I can't figure out how to create a DrawingPrintManager to use! You can see I've avoided this issue when creating my DrawingDocument object, as I just happened to know that there is an ActiveDocument attribute that I can get from the application itself.
I also:
don't know what the full list of attributes and methods for DrawingPrintManager are, so I don't know how to set a save location
don't know for sure that the two Enums I'm trying to use are actually defined within DrawingPrintManager, but I can figure that out once I actually have a DrawingPrintManager to work with
If anyone with more experience in using COM APIs or pywin32 can help me out, I'd be really appreciative. And the same if anyone can point me towards any actual documentation of Inventor's API Objects, which would make things a lot easier.
Thanks
Edit: After posting I've almost immediately found that I can get a PrintManager (can't tell if a PrintManager or DrawingPrintManager) by accessing drawing.PrintManager rather than drawing.DrawingPrintManager.
This is a workaround however as it doesn't answer my question of how to create objects within pywin32.
My problem moving forward is finding where I can access the PrintScaleModeEnum and PrintSizeEnum objects, and finding how to set the save location of the printed PDF (which I think will be a a separate question, as it's probably unrelated to the COM API).
I'm not familiar with python and pywin32, but I try to answer your questions.
Documentation of Inventor API is available in local installation "C:\Users\Public\Documents\Autodesk\Inventor 2020\Local Help" or online https://help.autodesk.com/view/INVNTOR/2020/ENU/
Generaly you are not able to create new instances of Inventor API objects. You must obtain them as a result of appropriate method or property value.
For example:
You CAN'T do this
doc = new Inventor.Document()
You MUST do this
doc = app.Documents.Add(...)
With print manager is this
print_manager = drawing.PrintManger
# this returns object of type Inventor.DrawingPrintManager
# when drawing is of type Inventor.DrawingDocument
See this for more details

How to correctly pass (mutable) objects using ROS-SMACH FSM

I've been struggling with this question for a while now. My question is very specific so please don't post a link to the ROS-tutorial page with the "!Note:" paragraph showing how to pass mutable objects (unless you show me something I have missed). I would like to know if anyone has been able to correctly pass mutable objects back and forth in SMACH states, without encountering any errors.
I wrote a particularly simple and useless program to explain what I am attempting to do. I could post the code of this example (unfortunately however, not surprisingly to those that have used SMACH before, it is a long piece of code). So for now I will just try my best to explain it and include a [link] to an image of my example. I created two python scripts. Each script contains a single class and object of that class (with some basic methods). I create a publisher and subscriber in each script, one of the scripts sends messages (talks) while the other script listens to (hears) the messages. At the end the talker flags both FSMs to shutdown. If anyone would like the full code example let me know...
Code snippet below showing smach states and transitions:
# begin sm
with sm:
smach.StateMachine.add('LOAD', loadFSM(),
transitions={'LOADED':'SENDMSG'})
smach.StateMachine.add('SENDMSG', startMSG(),
transitions={'SENT':'SENDMSG',
'ENDING':'END'})
smach.StateMachine.add('END', stopFSM(),
transitions={'DONE':'complete',
'ERRED':'incomplete'})
Code snippet below showing a smach state (loadFSM):
class loadFSM(smach.State):
def __init__(self):
smach.State.__init__(self, outcomes=['LOADED'],
output_keys=['talker_obj'],
input_keys=['talker_obj'])
# Initialise our talker object
self.talker = Talk()
def execute(self, userdata):
rospy.loginfo("talker state: Loading fsm")
self.talker.init_publish()
self.talker.init_subscribe()
userdata.talker_obj = self.talker
return 'LOADED'
The errors I receive (using Ubuntu 14.04, ROS indigo and python 2.7, not too sure but I believe the same errors occur in kinetic as well) only occur during state transitions and of course the introspective server does not work (does not show state transitions). The errors are;
1. "Exception in thread sm_introViewer:status_publisher:"
2. "Could not execute transition callback: Traceback (most recent call
last): File
"/opt/ros/indigo/lib/python2.7/dist-packages/smach/container.py",
line 175, in call_transition_cbs cb(self.userdata,
self.get_active_states(), *args)"
I also need to add, that my simple finite state machine example actually works and completes successfully, even my project's 2 larger FSMs complete. However, when the FSM has many states like in my project, sometimes my simulations fail. I would like to know from anyone who has used SMACH extensively if they think these errors are the cause or if they know for a fact that I am not passing the object correctly between states.
Thanks in Advance,
Tiz
I had similar problems in the past. If I remember correctly, userdata can only handle basic types (int, string, list, dict, ...) but not arbitrary objects.
I solved it by passing the objects to the constructor of state classes, instead of using the userdata, i.e. something like:
class myState(smach.State):
def __init__(self, obj):
smach.State.__init__(self, outcomes=['foo'], ...)
self.obj = obj
...
and then initialize like follows:
obj = SomeClass()
with sm:
smach.StateMachine.add('MY_STATE', myState(obj),
transitions={'foo':'bar'})
It is not so nice as it circumvents the userdata concept but it works.

How to get raw bytes from GLib.GString in Python?

I have an application written in Python using GTK3 through the GObject introspection (Python 2.7 and PyGObject 3.14). I am trying to load a web page using WebKit and access the contents of all the resources it loads. I'm able to accomplish this by connecting to the resource-load-finished signal of the WebKitWebView object I am using to load the page.
Within my signal handler I use the WebKitWebResource object in the web_resource parameter to access the loaded data. Everything works fine with the GLib.GString returned from get_data() when it does not contain a NULL byte, I can access what I need using data.str. However when the data does contain a NULL byte, which is often the case when the MIME type of the loaded resource is an image, data.len is correct but data.str only contains the data up to the first NULL byte. I can access the raw bytes by calling data.free_to_bytes() which returns a GLib.GBytes instance, however when the signal handler returns the application segfaults. I'm trying to access all the data within the loaded resource.
I hope the following code helps demonstrate the issue.
from gi.repository import Gtk
from gi.repository import WebKit
def signal_resource_load_finished(webview, frame, resource):
gstring = resource.get_data()
print(resource.get_mime_type())
desired_len = gstring.len
# gstring.str is missing data because it returns the data up to the first NULL byte
assert(gstring.str == desired_len) # this assertion fails
# calling this causes a segfault after the handler returns, but the data is accessible from gbytes.get_data()
#gbytes = gstring.free_to_bytes()
#assert(len(gbytes.get_data()) == desired_len) # this assertion succeeds before the segfault
return
webview = WebKit.WebView()
webview.connect('resource-load-finished', signal_resource_load_finished)
webview.connect('load-finished', Gtk.main_quit)
# lol cat for demo purposes of a resource containing NULL bytes (mime type: image/png)
webview.load_uri('http://images5.fanpop.com/image/photos/30600000/-Magical-Kitty-lol-cats-30656645-1280-800.png')
Gtk.main()
You don't want to use free_to_bytes as this will not only give you the bytes you want, but also release the string from memory without Python knowing about it - which, as you discovered, crashes your program. Unfortunately there isn't a corresponding get_bytes method as GLib.String wasn't really designed to hold binary data.
In fact I'd consider it a mistake in the WebKit API that the resource payload is only available as a GLib.String. They seem to have corrected this mistake in WebKit2: http://webkitgtk.org/reference/webkit2gtk/stable/WebKitWebResource.html
Consider switching to WebKit2 if you can (from gi.repository import WebKit2).

Loading a document on OpenOffice using an external Python program

I'm trying to create a python program (using pyUNO ) to make some changes on a OpenOffice calc sheet.
I've launched previously OpenOffice on "accept" mode to be able to connect from an external program. Apparently, should be as easy as:
import uno
# get the uno component context from the PyUNO runtime
localContext = uno.getComponentContext()
# create the UnoUrlResolver
resolver = localContext.ServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", localContext)
# connect to the running office
ctx = resolver.resolve("uno:socket,host=localhost,port=2002;"
"urp;StarOffice.ComponentContext")
smgr = ctx.ServiceManager
# get the central desktop object
DESKTOP =smgr.createInstanceWithContext("com.sun.star.frame.Desktop", ctx)
#The calling it's not exactly this way, just to simplify the code
DESKTOP.loadComponentFromURL('file.ods')
But I get an AttributeError when I try to access loadComponentFromURL. If I make a dir(DESKTOP), I've see only the following attributes/methods:
['ActiveFrame', 'DispatchRecorderSupplier', 'ImplementationId', 'ImplementationName',
'IsPlugged', 'PropertySetInfo', 'SupportedServiceNames', 'SuspendQuickstartVeto',
'Title', 'Types', 'addEventListener', 'addPropertyChangeListener',
'addVetoableChangeListener', 'dispose', 'disposing', 'getImplementationId',
'getImplementationName', 'getPropertySetInfo', 'getPropertyValue',
'getSupportedServiceNames', 'getTypes', 'handle', 'queryInterface',
'removeEventListener', 'removePropertyChangeListener', 'removeVetoableChangeListener',
'setPropertyValue', 'supportsService']
I've read that there are where a bug doing the same, but on OpenOffice 3.0 (I'm using OpenOffice 3.1 over Red Hat5.3). I've tried to use the workaround stated here, but they don't seems to be working.
Any ideas?
It has been a long time since I did anything with PyUNO, but looking at the code that worked last time I ran it back in '06, I did my load document like this:
def urlify(path):
return uno.systemPathToFileUrl(os.path.realpath(path))
desktop.loadComponentFromURL(
urlify(tempfilename), "_blank", 0, ())
Your example is a simplified version, and I'm not sure if you've removed the extra arguments intentionally or not intentionally.
If loadComponentFromURL isn't there, then the API has changed or there's something else wrong, I've read through your code and it looks like you're doing all the same things I have.
I don't believe that the dir() of the methods on the desktop object will be useful, as I think there's a __getattr__ method being used to proxy through the requests, and all the methods you've printed out are utility methods used for the stand-in object for the com.sun.star.frame.Desktop.
I think perhaps the failure could be that there's no method named loadComponentFromURL that has exactly 1 argument. Perhaps giving the 4 argument version will result in the method being found and used. This could simply be an impedance mismatch between Python and Java, where Java has call-signature method overloading.
This looks like issue 90701: http://www.openoffice.org/issues/show_bug.cgi?id=90701
See also http://piiis.blogspot.com/2008/10/pyuno-broken-in-ooo-30-with-system.html and http://udk.openoffice.org/python/python-bridge.html

Categories