Re: [PyQt] Fwd: Re: c++ app integrate PyQt

2013-10-01 Thread Mathias . Born
Hi,

In case you are on M$-WIndows, I'd like to mention a nasty bug in Visual C++ 
2012
that took me days to dig out of google:

http://bugs.python.org/issue17797

In short: when you embedd the python interpreter into an application compiled
as WINDOWS (not as CONSOLE), the operating system doesn't create stdin,
stdout and stderr. They just don't exist, which is perfectly normal for a 
Windows
GUI app. This is checked by Python. Older
versions of the MS runtime lib correctly reported these streams missing.
However, the runtime lib of VS2012 reports they exist even though they don't,
which finally raises an exception and prevents Python from initializing.

Microsoft knows:

http://connect.microsoft.com/VisualStudio/feedback/details/785119/

It might be possible that mingw users also run into this issue because it
relies on the MS runtime lib, too.

Best Regards,
Mathias


On 02.10.2013, 03:11:39 John Fabiani wrote:
  Original Message 
 Subject:  
 Re: [PyQt] c++ app integrate PyQt
 Date: 
 Mon, 30 Sep 2013 17:51:28 -0700
 From: 
 John Fabiani jo...@jfcomputer.com
 To: 
 Matt Newell newe...@blur.com


 On 09/30/2013 05:24 PM, Matt Newell wrote:
 On Monday, September 30, 2013 04:51:24 PM John Fabiani wrote:
 Hi,
 ...
 someone have an example or a link explaining the details.

 Johnf


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] PyQt5 Snapshot, build problems and their solutions, Windows, mingw

2013-07-07 Thread Mathias . Born
On 07.07.2013, 15:13:15 Phil Thompson wrote:
 On Sun, 12 May 2013 22:42:23 +0200, mathias.b...@gmx.de wrote:
 Hi,
 
 I've compiled the latest PyQt5 snaphot, on 32bit python 3.3.1 (compiled
 with mingw, using a self-made
 build script based on scons), Windows7, Qt 5.1alpha.
 
 I've used this configuration step:
 
 D:\_cpp_projects_\Python\Python-3.3.1\.build_release\python.exe
 configure.py --no-docstrings --confirm-license -u --spec=win32-g++
 --verbose --trace --sip=D:\_cpp_projects_\Python\Python-3.3.1\sip.exe
 LFLAGS+=-LD:\_cpp_projects_\Python\Python-3.3.1\.build_debug
 -LD:\_cpp_projects_\Python\Python-3.3.1\.build_release DEFINES+=_DEBUG
 
 (It's necessary to include the release version of the python lib even in
 debug build for the designer
 plugins.)
 
 I've run into a number of problems:
 
 (1)
 PyQt's configure.py autoamtically assumes certain MS-compilers on the
 win32 platform, in
 TargetConfiguration.__init__():262 and following:
 
 # The default qmake spec.
 if sys.platform == 'win32':
 if self.py_version = 0x030300:
 #self.qmake_spec = 'win32-msvc2010'
 self.qmake_spec = 'win32-g++'
 elif self.py_version = 0x020600:
 self.qmake_spec = 'win32-msvc2008'
 elif self.py_version = 0x020400:
 self.qmake_spec = 'win32-msvc.net'
 else:
 self.qmake_spec = 'win32-msvc'
 else:
 # Use the Qt default.  (We may update it for MacOS/X later.)
 self.qmake_spec = ''
 
 I had to make the marked change to get around that for my mingw-based
 python. It would be nice
 if there was an option to influence that.

 I don't understand why this is needed. Using the --spec option should do
 that.

 [Motivation: I must embedd the python interpreter, and I want to get
 away
 from MS Visual Studio,
 because it is becoming slower with each version. Hence I'll have to
 compile python myself using
 mingw, which is non-standard.]
 
 
 (2)
 All makefiles attempt to build all DLLs without referring to the python
 DLL. Adding
 -lpython33_d to each Makefile.Debug and -lpython33 to
 Makefile.Release
 solves this.
 
 I tried adding LFLAGS_DEBUG+=-lpython33_d as parameter to the
 configure
 script, but it had
 no effect on the makefiles.
 
 (3)
 The final debugging versions of the DLLs get the wrong names. They all
 miss the trailing _d.
 This way they can't be imported, unless manually renamed arcordingly.

 Try tonight's snapshot.

Thanks.
Using VS2012, it now works out of the box with python 3.3.2 and Qt 5.1.
Have not tested the mingw stuff yet.

Best Regards,
Mathias Born



___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] [SIP] is there a Qt5 example for SIP?

2013-07-07 Thread Mathias . Born
On 07.07.2013, 13:46:02 br...@stottlemyer.com wrote:
 On Sat, 6 Jul 2013 07:30:43 -0700, br...@stottlemyer.com wrote:
 Hi Phil,

 I am trying to see if SIP will help me with a task I'm trying to solve.
 I
 started out by trying the More Complex C++ Example in the docs.
 However,
 I'm using Qt5, and the example is for Qt4.

 I see the pyqtconfig is part of Qt4, but not Qt5.  No problem, except
 pyqtconfig is pretty integrated into the example, and as a beginner, I'm
 not sure how to take pyqtconfig out.

 Is there a Qt5 example for SIP?

 Look at the configure.py for PyQt5. A minimal build system would just be a
 shell script that invoked sip then the C++ compiler then the linker. The
 only thing you need to consider is to use the right -t flags to sip and
 these can be found by introspecting current versions of PyQt.

 Phil


 Thanks for the pointers.  I've got the example working.  But now I'm
 having trouble extending the example.

 I've got a bunch of enums I need to make available, some of which have
 overlapping names.  I've been handling this by putting them in different
 namespaces.  But sip is complaining about that.  I saw an old mailing list
 question on the topic
 (http://www.riverbankcomputing.com/pipermail/pyqt/2007-August/016847.html),
 but no solution was posted.

 My .h file is:
 // Define the interface to the hello library.

 #include qlabel.h
 #include qwidget.h
 #include qstring.h

 #if defined HELLO_DLL
 #  define HELLO_DLLSPEC  Q_DECL_EXPORT
 #else
 #  define HELLO_DLLSPEC Q_DECL_IMPORT
 #endif

 namespace MyNamespace { enum MyEnum { No=0, Yes=1}; };

 class HELLO_DLLSPEC Hello : public QLabel {
 // This is needed by the Qt Meta-Object Compiler.
 Q_OBJECT

 public:
 Hello(QWidget *parent = 0);

 private:
 // Prevent instances from being copied.
 Hello(const Hello );
 Hello operator=(const Hello );
 };

 #if !defined(Q_OS_WIN)
 void setDefault(const QString def);
 #endif

 My .sip file is:
 // Define the SIP wrapper to the hello library.

 %Module hello

 %Import QtGui/QtGuimod.sip
 %Import QtWidgets/QtWidgetsmod.sip

 %If (Qt_5_0_0 -)

 namespace MyNamespace
 {
 %TypeHeaderCode
 #include hello.h
 %End
 enum MyEnum { No=0, Yes=1};
 };

 class Hello : public QLabel {

 %TypeHeaderCode
 #include hello.h
 %End

 public:
 Hello(QWidget *parent /TransferThis/ = 0);

 private:
 Hello(const Hello );
 };

 %If (!WS_WIN)
 void setDefault(const QString def);
 %End

 %End

 The compiler (linker, actually) is complaining about missing symbols:
Creating library release\hello.lib and object release\hello.exp
 siphellocmodule.obj : error LNK2001: unresolved external symbol struct
 _pyqt4ClassTypeDef sipTypeDef_hello_MyNamespace
 (?sipTypeDef_hello_MyNamespace@@3U_pyqt4ClassTypeDef@@A)
 release\hello.dll : fatal error LNK1120: 1 unresolved externals

 What's the proper way to describe this to sip?

Hi,

Are you really compiling and linking all C++ files generated by SIP?

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


[PyQt] Bug: PyQt5.uic.loadUi() attempts to set non-existing property

2013-06-02 Thread Mathias . Born
Hi,

There appears to be an error in the loading of .ui files in PyQt5.
Please try the attached example.

Error message:

Traceback (most recent call last):
  File D:\eclipse.workspace\py_tests\src\uic_bug.py, line 15, in module
window = LogWindow()
  File D:\eclipse.workspace\py_tests\src\uic_bug.py, line 8, in __init__
PyQt5.uic.loadUi(os.path.join(os.path.dirname(__file__), 'log_window.ui'), 
self)
  File 
D:\_cpp_projects_\Python\Python-3.3.1\lib\site-packages\PyQt5\uic\__init__.py,
 line 224, in loadUi
return DynamicUILoader(package).loadUi(uifile, baseinstance, 
resource_suffix)
  File 
D:\_cpp_projects_\Python\Python-3.3.1\lib\site-packages\PyQt5\uic\Loader\loader.py,
 line 72, in loadUi
return self.parse(filename, resource_suffix, basedir)
  File 
D:\_cpp_projects_\Python\Python-3.3.1\lib\site-packages\PyQt5\uic\uiparser.py,
 line 931, in parse
actor(elem)
  File 
D:\_cpp_projects_\Python\Python-3.3.1\lib\site-packages\PyQt5\uic\uiparser.py,
 line 756, in createUserInterface
self.traverseWidgetTree(elem)
  File 
D:\_cpp_projects_\Python\Python-3.3.1\lib\site-packages\PyQt5\uic\uiparser.py,
 line 734, in traverseWidgetTree
handler(self, child)
  File 
D:\_cpp_projects_\Python\Python-3.3.1\lib\site-packages\PyQt5\uic\uiparser.py,
 line 444, in createLayout
self.stack.push(self.setupObject(classname, parent, elem))
  File 
D:\_cpp_projects_\Python\Python-3.3.1\lib\site-packages\PyQt5\uic\uiparser.py,
 line 161, in setupObject
self.wprops.setProperties(obj, branch)
  File 
D:\_cpp_projects_\Python\Python-3.3.1\lib\site-packages\PyQt5\uic\properties.py,
 line 415, in setProperties
getattr(widget, set%s%s % (ascii_upper(prop_name[0]), 
prop_name[1:]))(prop_value)
AttributeError: 'QHBoxLayout' object has no attribute 'setMargin'


The log_window.ui instantiates a QHBoxLayout, with all margins set to the same 
value. This makes
the uic module try to set a margin property, which doesn't exist.
Setting one of the margins (for example leftMargin) to a different value 
works.

Best Regards,
Mathias Born

log_window.ui
Description: Binary data
from PyQt5.QtWidgets import *
import PyQt5.uic, sys, os.path


class LogWindow(QFrame):
def __init__(self):
QFrame.__init__(self)
PyQt5.uic.loadUi(os.path.join(os.path.dirname(__file__), 
'log_window.ui'), self)

if __name__ == '__main__':

import sys

app = QApplication(sys.argv)
window = LogWindow()
window.show()
app.exec_()
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

[PyQt] PyQt5 Snapshot, build problems and their solutions, Windows, mingw

2013-05-12 Thread Mathias . Born
Hi,

I've compiled the latest PyQt5 snaphot, on 32bit python 3.3.1 (compiled with 
mingw, using a self-made
build script based on scons), Windows7, Qt 5.1alpha.

I've used this configuration step:

D:\_cpp_projects_\Python\Python-3.3.1\.build_release\python.exe configure.py 
--no-docstrings --confirm-license -u --spec=win32-g++ --verbose --trace 
--sip=D:\_cpp_projects_\Python\Python-3.3.1\sip.exe 
LFLAGS+=-LD:\_cpp_projects_\Python\Python-3.3.1\.build_debug 
-LD:\_cpp_projects_\Python\Python-3.3.1\.build_release DEFINES+=_DEBUG

(It's necessary to include the release version of the python lib even in debug 
build for the designer
plugins.)

I've run into a number of problems:

(1)
PyQt's configure.py autoamtically assumes certain MS-compilers on the win32 
platform, in
TargetConfiguration.__init__():262 and following:

# The default qmake spec.
if sys.platform == 'win32':
if self.py_version = 0x030300:
#self.qmake_spec = 'win32-msvc2010'
self.qmake_spec = 'win32-g++'
elif self.py_version = 0x020600:
self.qmake_spec = 'win32-msvc2008'
elif self.py_version = 0x020400:
self.qmake_spec = 'win32-msvc.net'
else:
self.qmake_spec = 'win32-msvc'
else:
# Use the Qt default.  (We may update it for MacOS/X later.)
self.qmake_spec = ''

I had to make the marked change to get around that for my mingw-based python. 
It would be nice
if there was an option to influence that.

[Motivation: I must embedd the python interpreter, and I want to get away from 
MS Visual Studio,
because it is becoming slower with each version. Hence I'll have to compile 
python myself using
mingw, which is non-standard.]


(2)
All makefiles attempt to build all DLLs without referring to the python DLL. 
Adding
-lpython33_d to each Makefile.Debug and -lpython33 to Makefile.Release 
solves this.

I tried adding LFLAGS_DEBUG+=-lpython33_d as parameter to the configure 
script, but it had
no effect on the makefiles.

(3)
The final debugging versions of the DLLs get the wrong names. They all miss the 
trailing _d.
This way they can't be imported, unless manually renamed arcordingly.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] General questions on parsing large QStrings

2013-05-12 Thread Mathias . Born
On 12.05.2013, 22:19:55 David Cortesi wrote:
 For an app to be built with PyQt5/Qt5, I will have a
 QPlainTextEdit in which the document may be quite
 sizable, 500K characters or more.

 I will want at times to inspect the document character
 by character, or possibly apply Python relib REs to it.

 I am somewhat at sea regarding the relationship between
 a const QString such as returned by QPlainTextEdit.toPlainText()
 and a Python3 unicode string, and -- just in general -- about
 the best way to do intensive examination of big strings.
 Is there a copy involved in, e.g.

 docstring = unicode( myEditor.toPlainText() )

 I note that the PyQt4 QString reference omits the 
 QString.begin() or .constBegin() etc methods that return an
 STL-style iterator so that's out. Is there some internal magic
 to integrate the QString type into Python's for mechanism
 so that for c in myEditor.toPlainText() might be more
 efficient than making a Python3 string and iterating on it?

 Also in regard to making intensive loops faster, 
 how well do PyQtx calls integrate with Cython or PyPy?

 Thanks for any insights,

 Dave Cortesi

Hi,

This is how you cand find out things like this yourself:

QPlainTextEdit.toPlainText() is wrapped in
python dir\sip\PyQt5\QtWidgets\qplaintextedit.sip as

QString toPlainText() const;

QString is not wrapped normally as class, but defined as a mapped
type in python dir\sip\PyQt5\QtCore\qstring.sip.
The part interesting you is the conversion C++ - Python:

%ConvertFromTypeCode
return qpycore_PyObject_FromQString(*sipCpp);
%End

This function can be found in the source code of PyQt5:

// Convert a QString to a Python Unicode object.
PyObject *qpycore_PyObject_FromQString(const QString qstr)
{
PyObject *obj;

#if defined(PYQT_PEP_393)
obj = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, qstr.constData(),
qstr.length());
#elif defined(Py_UNICODE_WIDE)
QVectoruint ucs4 = qstr.toUcs4();

if ((obj = PyUnicode_FromUnicode(NULL, ucs4.size())) == NULL)
return NULL;

memcpy(PyUnicode_AS_UNICODE(obj), ucs4.constData(),
ucs4.size() * sizeof (Py_UNICODE));
#else
if ((obj = PyUnicode_FromUnicode(NULL, qstr.length())) == NULL)
return NULL;

memcpy(PyUnicode_AS_UNICODE(obj), qstr.utf16(),
qstr.length() * sizeof (Py_UNICODE));
#endif

return obj;
}

As you can see, this will use a lot of memory in your case.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] faulty PyQt 4.10 Makefile on Windows

2013-04-21 Thread Mathias . Born
On 21.04.2013, 10:58:11 Phil Thompson wrote:
 On Sun, 21 Apr 2013 01:10:01 +0200, mathias.b...@gmx.de wrote:
 Hi,
 
 Both, the latest stable PyQt 4.10 as well as
 PyQt-win-gpl-snapshot-4.10.1-66f4c96140c6.zip
 generate Makefiles with errors on my Windows machine.
 
 Instead of
 
 @if not exist  
 D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4 mkdir 
  
  D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4
 
 I get
 
 @if not exist   # legacy
 D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4 mkdir 
  
 # legacy
 D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4
 
 in the 'install' target. Then, Microsoft nmake complains.
 
 Manually removing all # legacy fixed it. But I couldn't figure out
 which
 of the
 build tools put it in there.

 That will come from Qt. Which version of Qt?

 Phil

The official qt-everywhere-opensource-src-5.1.0-alpha.7z from
http://qt-project.org/wiki/Qt-5.1-Alpha

Compiled without errors.

Best Regards,
Mathias Born



___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] faulty PyQt 4.10 Makefile on Windows

2013-04-21 Thread Mathias . Born
On 21.04.2013, 11:37:50 Phil Thompson wrote:
 On Sun, 21 Apr 2013 11:25:15 +0200, mathias.b...@gmx.de wrote:
 On 21.04.2013, 10:58:11 Phil Thompson wrote:
 On Sun, 21 Apr 2013 01:10:01 +0200, mathias.b...@gmx.de wrote:
 Hi,
 
 Both, the latest stable PyQt 4.10 as well as
 PyQt-win-gpl-snapshot-4.10.1-66f4c96140c6.zip
 generate Makefiles with errors on my Windows machine.
 
 Instead of
 
 @if not exist  
 D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4
 mkdir 
  
  D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4
 
 I get
 
 @if not exist   # legacy
 D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4
 mkdir 
  
 # legacy
 D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4
 
 in the 'install' target. Then, Microsoft nmake complains.
 
 Manually removing all # legacy fixed it. But I couldn't figure out
 which
 of the
 build tools put it in there.
 
 That will come from Qt. Which version of Qt?
 
 Phil
 
 The official qt-everywhere-opensource-src-5.1.0-alpha.7z from
 http://qt-project.org/wiki/Qt-5.1-Alpha
 
 Compiled without errors.

 ...so a Qt bug.

 Phil

I find that very strange. Are you saying that a Qt bug changes a
Makefile in _your_ PyQt package where it attempts to copy
the modules to ..\Lib\site-packages\PyQt4?

Admittedly, I couldn't find the text # legacy anywhere in sip, nor
in PyQt.
Even if it is a Qt bug, would you not be interested in knowing more about it?
It prevents building PyQt ...

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


[PyQt] faulty PyQt 4.10 Makefile on Windows

2013-04-20 Thread Mathias . Born
Hi,

Both, the latest stable PyQt 4.10 as well as 
PyQt-win-gpl-snapshot-4.10.1-66f4c96140c6.zip
generate Makefiles with errors on my Windows machine.

Instead of

@if not exist   
D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4 mkdir   
D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4

I get

@if not exist   # legacy 
D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4 mkdir  # 
legacy D:\_cpp_projects_\Python\Python-3.3.0\Lib\site-packages\PyQt4

in the 'install' target. Then, Microsoft nmake complains.

Manually removing all # legacy fixed it. But I couldn't figure out which of 
the
build tools put it in there.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] selecting a bezier curve

2013-04-14 Thread Mathias . Born
Hi,

I'd like to point out that, realistically, the QGraphicsView framework
is obsolete. Yes, it may still be around a while.
But: The new OpenGL based QtQuick 2.0 graphics stack is way better.

I'm in the process of porting a C++ application from QGraphicsView
to QtQuick 2.0, which used a lot of custom QGraphicsItems which are
now QQuickItems. The performance increase is unbelieveable. And it's
more powerful and has more features, too!

I was very sceptical at first, as this make me dependent on hardware
accelerated OpenGL now. But in the year 2013 this is really no problem.

Of course, right now QtQuick 2.0 is out of reach for PyQt users.
But that will change. And the new model fits the Python approach
much better. In QGraphicsView, Python code is run every time a frame
is drawn. In QtQuick, your Python code generates a description of the
scene once, which is then drawn by the 3D-chip exclusively. Very fast.

Best Regards,
Mathias Born



On 14.04.2013, 02:15:16 Tom Brown wrote:
 I've created a simple application (see below) that draws a bezier
 curve. I want to give the user the ability to select the curve so
 they can move it around. However, I'm having trouble selecting the
 curve in an intuitive fashion. When I click on the curve, the point
 I click on is actually far away from the curve.
 ...

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


[PyQt] Bug report, compiling latest snapshots against Qt5 on Windows

2013-01-24 Thread Mathias . Born
Hi,

I'm getting errors running PyQt's configure.py.
Cause:
Starting in line 954, the file sipconfig.py of the sip module contains:

if sys.platform == win32 and shared in 
self.config.qt_winconfig.split():
if (mname in (QtCore, QtDeclarative, QtDesigner, QtGui,
  QtHelp, QtMultimedia, QtNetwork, QtOpenGL,
  QtScript, QtScriptTools, QtSql, QtSvg,
  QtTest, QtWebKit, QtXml, QtXmlPatterns,
  phonon) or
(qt_version = 0x040200 and mname == QtAssistant)):
lib = lib + 4

if sys.platform.startswith(linux) and qt_version = 0x05:
lib = Qt5 + lib[2:]

However, my Qt5 build created libraries named Qt5Gui.lib and so on, not
QtGui4.lib.
If I replace

   lib = lib + 4

by

   lib = Qt5 + lib[2:]

I get the right library names, but then I get linker errors due to missing
symbols from the Qt5Widgets.lib, which the script seems to miss as
dependency.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


[PyQt] bug in pyqt's configure.py

2013-01-21 Thread Mathias . Born
Hi,

In the latest snapshot (PyQt-win-gpl-snapshot-4.10-f0118624625e.zip),
I noticed an error in its configure.py when run on Python 3.3.

lines 1925 to 1931 read:

# Qt5 doesn't have the 'default' link.
if not os.path.isdir(fname):
f = get_command_stdout(opts.qmake +  -query QMAKE_SPEC)
fname = f.read().strip()
f.close()

fname = os.path.join(qt_datadir, mkspecs, fname)

The problem here is that

fname = f.read().strip()

creates a byte array, not a string, which makes

fname = os.path.join(qt_datadir, mkspecs, fname)

fail, because qt_datadir is a string.


These possible fixes come to my mind:

(1) Just add decode to the reading:

 fname = f.read().strip().decode()

(2) Change function get_command_stdout in line 1401:

p = subprocess.Popen(cmd, shell=True, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=stderr, env=env, 
universal_newlines=True)

  However, this most likely will break other parts.


Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Help tracking down intermittent segfault using QGraphicsItem

2013-01-05 Thread Mathias . Born
Lee,

I tried pynguin-0.12.zip on Windows7, python 2.7, PyQt 4.8.4 32bit,
and I could run go() many times without any crashes or warnings.
However, there appears to be no tournament function.

One advise, if I may say so: The chance of finding someone who would
be willing to debugg your entire project is slim. On a mailing list
such as this one, the best way is to reduce the problem to a self
contained, minimum size test case which reproduces the bug.

Best Regards,
Mathias Born

On 05.01.2013, 05:11:10 Lee Harr wrote:

 I develop a free python turtle graphics application:
 http://pynguin.googlecode.com/

 Right now I am trying to track down and fix an intermittent
 segfault involving a QGraphicsScene and QGraphicsItem

 Here is what I have...

 a QGraphicsItem subclass (item0) created with parent=None
 another QGraphicsItem subclass (item1) created with parent=item0

 I then add item0 to my scene and things appear to be
 working fine, but when removing and adding instances
 of this arrangement in rapid succession I will soon get
 a segfault.

 If you want to play along at home, load the horserace.pyn
 example and run the tournament function. For me it will
 crash reliably within the first 2 or 3 races.

 In this case, item1 represents the text labels for the horses.
 If I remove the labels, I never see the segfault.

 The strangest part is that if I manually add item1 to the scene
 (should not be needed since the child is automatically added when
 the parent is added) I do not get the segfault.

 The only problem with this is that I get a warning:
 QGraphicsScene::addItem: item has already been added to this scene


 So... my questions:

 What is most likely to be the real problem here?

 How likely is it that if I get it to the point that there is no segfault
 on my machine (ie, just leave in the code that generates the warning)
 that it won't segfault on a different OS/architecture?

 What is the best way to go about tracking down and fixing the real problem?


 Thanks for any assistance.

   
 ___
 PyQt mailing listPyQt@riverbankcomputing.com
 http://www.riverbankcomputing.com/mailman/listinfo/pyqt

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Help tracking down intermittent segfault using QGraphicsItem

2013-01-05 Thread Mathias . Born
On 05.01.2013, 16:50:29 Andreas Pakulat wrote:
[...]
 Often a segfault is caused by using a pointer (in C++) which points to
 a memory location thats not valid anymore, for example because the
 object has been deleted already. In the context of PyQt this can
 happen when you stop keeping references to objects that or instances
 of C++-provided classes in python. In such a case the C++ parts of the
 object will be deleted and thus any other C++ code that has a
 reference to the object will crash when it tries to access the object.
 I think thats the most common problem one encounters with PyQt4.

While this is certainly true in general, I'd say that sip goes to
great length in order to avoid that kind of crash by carefully
observing who owns what. It is aware of the parent-child memory
management of Qt. A python program should never be able to cause a
crash. Is there any place in PyQt where the Python code has to keep
references to keep the program going?

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] Help tracking down intermittent segfault using QGraphicsItem

2013-01-05 Thread Mathias . Born
On 05.01.2013, 22:58:28 Andreas Pakulat wrote:
 Hi,

 Am Samstag, 5. Januar 2013 schrieb :
 On 05.01.2013, 16:50:29 Andreas Pakulat wrote:
 [...]
 Often a segfault is caused by using a pointer (in C++) which points to
 a memory location thats not valid anymore, for example because the
 object has been deleted already. In the context of PyQt this can
 happen when you stop keeping references to objects that or instances
 of C++-provided classes in python. In such a case the C++ parts of the
 object will be deleted and thus any other C++ code that has a
 reference to the object will crash when it tries to access the object.
 I think thats the most common problem one encounters with PyQt4.

 While this is certainly true in general, I'd say that sip goes to
 great length in order to avoid that kind of crash by carefully
 observing who owns what. It is aware of the parent-child memory
 management of Qt. A python program should never be able to cause a
 crash. Is there any place in PyQt where the Python code has to keep
 references to keep the program going?

 Thats not always possible, it only works for objects which tell sip
 when they are deleted, for example QObject instances. Other Qt types
 do not support object life tracking like QObject, so sip has no way
 to know that it should not delete the object when the python reference is 
 garbage collected.

That's why you have to specify ownership in sip files and when using
sip from the C++ side. sip doesn't actually track anything. If an
object is owned by the Python side, the wrapped C++ part is destroyed
when the reference count of the wrapper becomes zero. If it is owned
by C++, the wrapper is deleted, but the C++ object stays alive.

Erik Janssens posted this example:

from PyQt4 import QtGui
app = QtGui.QApplication([])
window = QtGui.QMainWindow()
statusbar = window.statusBar()
del window
statusbar.objectName()

which causes a crash in the last line, because window is gone along
with the real (C++)statusbar, but the Python wrapper statusbar still
exists without its C++ counterpart. That's because the QMainWindow instance
is created by Python and thus owned by Python.

In qmainwindow.sip:

QStatusBar *statusBar() const /Transfer/;

where /Transfer/ means:

In the case of methods returned values (unless they are new references to 
already
wrapped values) are normally owned by C++ anyway. However, in addition, an 
association
between the returned value and the instance containing the method is created 
with
regard to the cyclic garbage collector. (from the docs)

If statusbar were given an extra reference to window, the crash could be 
avoided,
but then del window would not delete the window anymore. This would be safer,
but sip currently doesn't do that.

Best Regards,
Mathias Born

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] A gobal variable problem in sip

2012-10-24 Thread Mathias . Born
On 24.10.2012, 00:11:13 D.Y Feng wrote:
 I meet a problem in my code:

 hello.h:

 #includeQtCore

 class Hello : public QObject{
 Q_OBJECT
 public:
 Hello(QObject *parent = 0);
 static int test(){
 static int i=0;
 qDebug()i++;
 return 0;
 }
 };

 hello.cpp:
 #include hello.h

 const int i=Hello::test();

 Hello::Hello (QObject *parent)
 {
 }

 hello.sip

 %Module hello

 %Import QtCore/QtCoremod.sip


 class Hello : public QObject {

 %TypeHeaderCode
 #include hello.h
 %End

 public:
  Hello(QObject *parent = 0);
  static int test();
 };

 I use the const int i=Hello::test(); to invoke test() before main
 function.It's uesful in factory pattern when you want to auto  register 
 driver.

 the python test code
 import hello
 hello.Hello.test1()

 It seems static int i  in test() changed after import hello

Now, I haven't tried that myself yet. On the other hand, I don't see any
problem.

 Breakpoint 1, Hello::test1 () at hello.h:8
 8   static int test1(){
 (gdb) p i
 $1 = 0
 (gdb) p i
 $2 = (const int *) 0x760300d0

This displays the address of your global variable const int i.

 (gdb) c
 Continuing.
 0 

 Breakpoint 1, Hello::test1 () at main.h:8
 8   static int test1(){
 (gdb) p i
 $3 = (const int *) 0x760300d0

Again, address of your global variable const int i.

 (gdb) n
 10  qDebug()i++;
 (gdb) p i
 $4 = (int *) 0x762355c0   ---What happen here?

This shows the address of your local static variable static int i,
which ought to be different.
The names of these objects, which are both i, come into existence at
different times. While this is perfectly legal C++, it obviously
obfuscates your program. Just naming them differently should already
help a lot.

In summary, I don't think this is an issue with PyQt. But let me quote
Bjarne Stroustrup: C makes it easy to shoot yourself in the foot; C++
makes it harder, but when you do it blows your whole leg off.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: add new annotation for specifying ownership of results of virtual methods

2012-09-21 Thread Mathias . Born
On 21.09.2012, 16:28:20 Phil Thompson wrote:
 On Mon, 3 Sep 2012 22:27:41 +0200, mathias.b...@gmx.de wrote:
 Hi Phil,
 
 I've come across a case which I think deserves its own function
 annotation.
 This is the proplem:
 
 I'm embedding Python code into a C++ app. There are two wrapped classes:
 
 class Netlister
 {
   virtual ~Netlister();
   ...
 };
 
 and
 
 class Project
 {
   virtual ~Project();
   ...
   virtual NetLister* netLister(const std::string netListText)
 const;
 };
 
 In Python, I have (ltse_app is the C++ app exposed as module)
 
 
 class LTspiceNetLister(ltse_app.NetLister):
   ...
 
 and
 
 class Project(ltse_app.Project):
   ...
   def netLister(self, netListText):
 return LTspiceNetLister()
 
 
 First, I call a Python function which gives me an instance of the Python
 class Project. Then (in C++, using its wrapper), I call its method
 netLister,
 which returns an instance of LTspiceNetLister. The goal is to use
 this instance on the C++ side via its wrapper. Thus, ownership should be
 with C++.
 
 But there is no corresponding annotation for the sip file. I have to
 provide
 a %VirtualCatcherCode:
 
 virtual NetLister* netLister(const std::string netListText /NoCopy/)
 const;
 %VirtualCatcherCode
 PyObject *resObj = sipCallMethod(0, sipMethod, D,
 const_caststd::string*(a0), sipType_std_string, NULL);
 sipIsErr = !resObj || sipParseResult(0, sipMethod, resObj, H0,
 sipType_NetLister, sipRes)  0;
 if (!sipIsErr) sipTransferTo(resObj, Py_None);
 Py_XDECREF(resObj);
 %End
 
 Note how I use sipTransferTo(resObj, Py_None); to bind the Python
 object
 to the C++ instance.
 I'm basically asking for something like the Factory annotation which
 does just that.
 
 Factory tells sip that a wrapped C++ function creates a new object
 that
 will be owned by the
 Python side. I'd like to have another annotation which tells sip that
 the
 Python implementation
 of a class method creates a new object that will be owned by the C++
 side.

 The documentation for /Factory/ is wrong (now fixed in hg). It effectively
 does...

 sipTransferTo(resObj, selfObj);

 ...in the virtual catcher (where selfObj) is the class's self object (the
 Project instance in this case). You are using Py_None but I don't think it
 would make a difference.

 Would this remove your use case for sipTransfer(obj, Py_None)?

 Phil

No it wouldn't. My embedding currently works like this: I have a .py file
which is imported as module at program start. This module defines a
factory function, which is called from C++ and returns an instance of
a Python class derived from a sip-wrapped C++ class (Project). The
PyObject* obtained this way is then fed into sip's api_convert_to_type
to get hold of the wrapper instance. This instance is then used in the
C++ code. It transparently forwards method calls to the Python part.
(That's why it was so important to have the wrapper re-throw Python
exceptions as C++ exceptions.)
Thanks to sipTransfer(obj, Py_None) I don't have to manually manage the
PyObject representing the Python part. It just gets automatically deleted
by the C++ wrapper.

Further, your sipTransferTo(resObj, selfObj); above would bind the returned
NetLister to the Project instance. But they are not related in terms
of life time. I only want the reference count of the Python part to be decreased
by one when the C++ wrapper is destroyed. Provided there are no further
references on the Python side, this automatically destroys the Python part, too.

No parent-child relationships here like in Qt. Just Python objects that can be
used in C++ as if they were C++ only.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: template %MappedType doesn't allow /AllowNone/

2012-09-19 Thread Mathias . Born
On 19.09.2012, 22:19:45 mathias.b...@gmx.de wrote:
 On 18.09.2012, 11:02:34 Phil Thompson wrote:

 A thought...

 Did you update from hg or use a snapshot?

 If hg did you change to the default branch?

 Phil

 I had not changed the branch. Now I have, and

 hg identify

 says 6d704a7ab6c5 tip.

 But now sip.exe crashes with my sip file. Don't have time right now
 to look at it, though.

 Best Regards,
 Mathias Born

I believe you need to add

  spec-errorhandlers = NULL;

to the parse function in parser.y of sipgen (line 4326).
This stops sip.exe from crashing for me.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: extend exception support

2012-09-19 Thread Mathias . Born
On 19.09.2012, 11:07:14 Phil Thompson wrote:
 On Mon, 17 Sep 2012 22:25:59 +0200, mathias.b...@gmx.de wrote:
 On 17.09.2012, 22:14:49 Phil Thompson wrote:
 On Mon, 27 Aug 2012 12:10:23 -0700, Matt Newell newe...@blur.com
 wrote:
 
 The difference is the access to the (not necessarily present)
 objects.
 How
 are you getting these?
 
 Phil
 
 Here's the patch against a quite old hg checkout.
 
 After several more iterations (ok, rewrites) the implementation in the
 current snapshot should be Ok - and work with %Imported modules.
 
 Phil
 
 I'm pleased to report that this works fine for me. Some comments:
 
 In the docs about the %DefaultVirtualErrorHandler directive, there is
 a
 typo
 
 %DefaultVirtualErrorHandle my_handler
 
 which should read
 
 %DefaultVirtualErrorHandler my_handler
 
 
 In addition, the function type is not
 
 void my_handler(sip_gilstate_t, PyObject *);
 
 but instead
 
 void my_handler(sip_gilstate_t, sipSimpleWrapper*);

 You need to use the default branch (or a snapshot) - I changed it all
 again.

Ok, but that's not working properly anymore.

sip.h declares

typedef void (*sipVirtErrorHandlerFunc)(struct _sipSimpleWrapper *);

but the generated code containes error handlers that look like

void sipVEH_ltse_app_defaultVirtualErrorHandler(sip_gilstate_t, PyObject *)

And inside other functions they are referred to as, for example

extern void sipVEH_ltse_app_defaultVirtualErrorHandler(sip_gilstate_t, PyObject 
*);

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: template %MappedType doesn't allow /AllowNone/

2012-09-18 Thread Mathias . Born
On 18.09.2012, 11:02:34 Phil Thompson wrote:

 A thought...

 Did you update from hg or use a snapshot?

 If hg did you change to the default branch?

 Phil

I had not changed the branch. Now I have, and

hg identify

says 6d704a7ab6c5 tip.

But now sip.exe crashes with my sip file. Don't have time right now
to look at it, though.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: template %MappedType doesn't allow /AllowNone/

2012-09-17 Thread Mathias . Born
On 17.09.2012, 18:44:19 Phil Thompson wrote:
 On Mon, 10 Sep 2012 23:31:20 +0200, mathias.b...@gmx.de wrote:
 Phil,
 
 While using /AlloNone/ on a normal mapped type directive like
 
 %MappedType boost::optionalfs::path /AllowNone/
 
 works, sip tells me
 
 Deprecation warning : type_mappings.sip.h:269: Annotation is invalid
 
 for
 
 templateType
 %MappedType boost::optionalType /AllowNone/
 
 If this is intended, why this limitiation?

 Lazy programming on my part - fixed in hg.

 Phil

I finally got around updating, but I still get the same error message.

Best Regards,
Mathias


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: extend exception support

2012-09-17 Thread Mathias . Born
On 17.09.2012, 22:14:49 Phil Thompson wrote:
 On Mon, 27 Aug 2012 12:10:23 -0700, Matt Newell newe...@blur.com wrote:
 
 The difference is the access to the (not necessarily present) objects.
 How
 are you getting these?
 
 Phil
 
 Here's the patch against a quite old hg checkout.

 After several more iterations (ok, rewrites) the implementation in the
 current snapshot should be Ok - and work with %Imported modules.

 Phil

I'm pleased to report that this works fine for me. Some comments:

In the docs about the %DefaultVirtualErrorHandler directive, there is a typo

%DefaultVirtualErrorHandle my_handler

which should read

%DefaultVirtualErrorHandler my_handler


In addition, the function type is not

void my_handler(sip_gilstate_t, PyObject *);

but instead

void my_handler(sip_gilstate_t, sipSimpleWrapper*);


Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: template %MappedType doesn't allow /AllowNone/

2012-09-13 Thread Mathias . Born
On 13.09.2012, 18:44:19 Phil Thompson wrote:
 On Mon, 10 Sep 2012 23:31:20 +0200, mathias.b...@gmx.de wrote:
 Phil,
 
 While using /AlloNone/ on a normal mapped type directive like
 
 %MappedType boost::optionalfs::path /AllowNone/
 
 works, sip tells me
 
 Deprecation warning : type_mappings.sip.h:269: Annotation is invalid
 
 for
 
 templateType
 %MappedType boost::optionalType /AllowNone/
 
 If this is intended, why this limitiation?

 Lazy programming on my part - fixed in hg.

 Phil

Great, thanks!

Best Regards,
Mathias Born

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


[PyQt] sip: template %MappedType doesn't allow /AllowNone/

2012-09-10 Thread Mathias . Born
Phil,

While using /AlloNone/ on a normal mapped type directive like

%MappedType boost::optionalfs::path /AllowNone/

works, sip tells me

Deprecation warning : type_mappings.sip.h:269: Annotation is invalid

for

templateType
%MappedType boost::optionalType /AllowNone/

If this is intended, why this limitiation?

Best Regards,
Mathias Born



___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


[PyQt] sip: add new annotation for specifying ownership of results of virtual methods

2012-09-03 Thread Mathias . Born
Hi Phil,

I've come across a case which I think deserves its own function annotation.
This is the proplem:

I'm embedding Python code into a C++ app. There are two wrapped classes:

class Netlister
{
  virtual ~Netlister();
  ...
};

and

class Project
{
  virtual ~Project();
  ...
  virtual NetLister* netLister(const std::string netListText) const;
};

In Python, I have (ltse_app is the C++ app exposed as module)


class LTspiceNetLister(ltse_app.NetLister):
  ...

and

class Project(ltse_app.Project):
  ...
  def netLister(self, netListText):
return LTspiceNetLister()


First, I call a Python function which gives me an instance of the Python
class Project. Then (in C++, using its wrapper), I call its method 
netLister,
which returns an instance of LTspiceNetLister. The goal is to use
this instance on the C++ side via its wrapper. Thus, ownership should be with 
C++.

But there is no corresponding annotation for the sip file. I have to provide
a %VirtualCatcherCode:

virtual NetLister* netLister(const std::string netListText /NoCopy/) const;
%VirtualCatcherCode
PyObject *resObj = sipCallMethod(0, sipMethod, D, 
const_caststd::string*(a0), sipType_std_string, NULL);
sipIsErr = !resObj || sipParseResult(0, sipMethod, resObj, H0, 
sipType_NetLister, sipRes)  0;
if (!sipIsErr) sipTransferTo(resObj, Py_None);
Py_XDECREF(resObj);
%End

Note how I use sipTransferTo(resObj, Py_None); to bind the Python object to 
the C++ instance.
I'm basically asking for something like the Factory annotation which does 
just that.

Factory tells sip that a wrapped C++ function creates a new object that will 
be owned by the
Python side. I'd like to have another annotation which tells sip that the 
Python implementation
of a class method creates a new object that will be owned by the C++ side.

Best Regards,
Mathias Born




___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: how to make a python instance owned by C++ without using a parent

2012-08-27 Thread Mathias . Born
On 27.08.2012, 22:50:43 Phil Thompson wrote:
 On Sun, 26 Aug 2012 21:11:50 +0200, mathias.b...@gmx.de wrote:
 On 26.08.2012, 18:15:55 Phil Thompson wrote:
 On Wed, 15 Aug 2012 11:55:47 +0200, mathias.b...@gmx.de wrote:
 On 15.08.2012, 11:05:42 Phil Thompson wrote:
 I could change sipTransferTo() to do this if the owner was Py_None.
 At
 the
 moment this is undocumented behaviour. Would this be sufficient?
 
 I believe so.
 
 Done in hg.
 
 Phil,
 
 First tests show that this works well. It's an important feature, but
 burried deeply in the documentation, well, actually sort of obscured.
 
 Function sipConvertToType is documented as:
 
 If transferObj is NULL then the ownership is unchanged. If it is Py_None
 then
 ownership is transferred to Python via a call to sipTransferBack().
 Otherwise ownership is transferred to C/C++ and obj associated with
 transferObj via a call to sipTransferTo().
 
 Function sipTransferTo tells us:
 ... If owner is Py_None then obj is given an extra reference which is
 removed when the C++ instance’s destructor is called. ...
 
 
 Since sipTransferTo is mentioned by the docs of sipConvertToType,
 who
 would guess that Py_None has such a different meaning?
 
 How about adding a corresponding hint to the documentation
 of sipConvertToType?

 I'm not sure that adding documentation to something about what it doesn't
 do makes anything clearer.

 Phil

That's because you are far too familiar with sip :-)

I imagine adding something like

Note that obj can also be managed by the C++ instance itself, but this
can only be achieved by using sipTransferTo.

to the documentation of sipConvertToType.

Best Regards,
Mathias Born

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt

Re: [PyQt] sip: extend exception support

2012-08-27 Thread Mathias . Born
On 27.08.2012, 14:34:10 Phil Thompson wrote:
 On Sun, 26 Aug 2012 22:22:40 +0200, mathias.b...@gmx.de wrote:
 On 26.08.2012, 16:07:52 Phil Thompson wrote:
 On Sun, 26 Aug 2012 14:30:32 +0200, mathias.b...@gmx.de wrote:
 On 26.08.2012, 16:46:24 Phil Thompson wrote:
 On Wed, 15 Aug 2012 15:54:11 +0200, mathias.b...@gmx.de wrote:
 ...
 
 Should all be fixed in current hg and tonight's snapshot.
 
 Thanks,
 Phil
 
 
 Ok, I pulled from the hg and could build everything. Quite nifty.
 One can now use class instances implemented in python just like
 normal C++ without any additional worries.
 
 One issue though. Discussions like
 
 http://www.boost.org/community/error_handling.html
 
 suggest that SIPPyException should be derived from std::exception.
 My original suggestion was a bit short-sighted. It would be even
 better to let the user define his own exception class.
 
 I'm using sip to embed python code into a Qt/C++ program. Every
 exception is reported to the user via a message box:
 
 catch(std::exception const exc)
 {
   QMessageBox(QMessageBox::Critical, Error, exc.what(),
   QMessageBox::Ok).exec();
 }
 
 With SIPPyException the way it is, I need to add another exception
 handler everywhere:
 
 catch(SIPPyException const)
 {
   QMessageBox(QMessageBox::Critical, Error, pythonExceptionToText(),
   QMessageBox::Ok).exec();
 }
 
 If I could provide a function to call instead of just doing
 throw SIPPyException(), I could throw an exception there myself
 as I see fit. For example, there could be a directive
 
 %MethodErrorHandlerCode
   throw std::runtime_error(pythonExceptionToText());
 %End
 
 which would follow the %Module directive to define the body of an
 error handler function which is called instead of throw
 SIPPyException().
 
 Best Regards,
 Mathias

 In current hg...

 %VirtualErrorCode is a new sub-directive of the %Module directive.

 all_throw_cpp_exception replaced by all_use_VirtualErrorCode.

 /ThrowsCppException/ replaced by /UsesVirtualErrorCode/.

 /NoThrowsCppException/ replaced by /NoUsesVirtualErrorCode/.

 Removed SIPPyException.

 Phil

Great!
I tested this, works fine. Thank you for providing this feature.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: extend exception support

2012-08-26 Thread Mathias . Born
On 26.08.2012, 16:46:24 Phil Thompson wrote:
 On Wed, 15 Aug 2012 15:54:11 +0200, mathias.b...@gmx.de wrote:
 Phil,
 
 sip can already propagate C++ exceptions into Python in cases
 where Python calls a C++ function which throws an exception.
 
 However, if I extend a C++ class in Python and call a corresponding
 (Python-)method in C++ via the wrapper, the sip generated
 wrapper code checks for a Python exception, but doesn't throw an
 excpetion itself.
 For example:
 
 = code generated by sip ===
 boost::optionalint sipVH_ltse_app_0(sip_gilstate_t
 sipGILState,PyObject
 *sipMethod,const std::string a0)
 {
 boost::optionalint sipRes;
 PyObject *resObj = sipCallMethod(0,sipMethod,N,new
 std::string(a0),sipType_std_string,NULL);
 
 if (!resObj ||

 sipParseResult(0,sipMethod,resObj,H5,sipType_boost_optional_1800,sipRes)
  0)
 PyErr_Print();
 
 Py_XDECREF(resObj);
 Py_DECREF(sipMethod);
 
 SIP_RELEASE_GIL(sipGILState)
 
 return sipRes;
 }
 =
 
 Here, PyErr_Print is called if the Python implementation of
 the method raises an exception. This is fine for Qt which
 cannot deal with exceptions, but in general I would find it
 much more helpful if the wrapper code generated by sip
 threw a C++ exception itself to signal the problem to the
 caller.
 
 Just define a class, e.g. SIPPyException (derived from
 std::exception), which becomes part of the API and is always used
 in such cases.
 In order not to break existing code, it would only be used in
 classes or methods which are annotated appropriately.
 (So an additional annotation is necessary to activate this behavior.)
 
 I believe an extension like this would make sip a lot more useful
 for embedding Python into a C++ program.
 
 Best Regards,
 Mathias Born

 Try current hg or tonight's snapshot. See the all_throw_cpp_exception
 %Module argument and the /ThrowsCppException/ and /NoThrowsCppException/
 function annotations.

 Not heavily tested.

That's great!
I tried sip-4.13.4-snapshot-5f97352e818f.zip.

When buidling sip, my MSVC2010 complains:

sip.h(347) : error C2016: C requires that a struct or union has at least one 
member

Possible fix: just change

struct SIPPyException {};

to

#ifdef __cplusplus
struct SIPPyException {};
#endif

That should be ok because it's for an exception, a C++ only feature.


The generated code, for example:

= code generated by sip ===
std::string sipVH_ltse_app_1(sip_gilstate_t sipGILState,PyObject 
*sipMethod,const std::string a0)
{
std::string sipRes;
PyObject *resObj = sipCallMethod(0,sipMethod,N,new 
std::string(a0),sipType_std_string,NULL);

if (!resObj || 
sipParseResult(0,sipMethod,resObj,H5,sipType_std_string,sipRes)  0)
throw SIPPyException();

Py_XDECREF(resObj);
Py_DECREF(sipMethod);

SIP_RELEASE_GIL(sipGILState)

return sipRes;
}
=

will leak memory, though. All the

Py_XDECREF(resObj);
Py_DECREF(sipMethod);
SIP_RELEASE_GIL(sipGILState)

won't be executed in case of an exception.


In addition, I get a lot of compilation errors when I try to build PyQt v4.9.4 
with this new sip,
for example:

.\sipQtGuiQFontDialog.cpp(3298) : error C2664: 'void QFontDialog::open(QObject 
*,const char *)' : cannot convert parameter 1 from 'QObject **' to 'QObject *'
Types pointed to are unrelated; conversion requires reinterpret_cast, 
C-style cast or function-style cast

That's a show stopper, as my stuff can't do without PyQT ...

Best Regards,
Mathias Born

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: extend exception support

2012-08-26 Thread Mathias . Born
On 26.08.2012, 16:07:52 Phil Thompson wrote:
 On Sun, 26 Aug 2012 14:30:32 +0200, mathias.b...@gmx.de wrote:
 On 26.08.2012, 16:46:24 Phil Thompson wrote:
 On Wed, 15 Aug 2012 15:54:11 +0200, mathias.b...@gmx.de wrote:
 ...

 Should all be fixed in current hg and tonight's snapshot.

 Thanks,
 Phil


Ok, I pulled from the hg and could build everything. Quite nifty.
One can now use class instances implemented in python just like
normal C++ without any additional worries.

One issue though. Discussions like

http://www.boost.org/community/error_handling.html

suggest that SIPPyException should be derived from std::exception.
My original suggestion was a bit short-sighted. It would be even
better to let the user define his own exception class.

I'm using sip to embed python code into a Qt/C++ program. Every
exception is reported to the user via a message box:

catch(std::exception const exc)
{
  QMessageBox(QMessageBox::Critical, Error, exc.what(), 
QMessageBox::Ok).exec();
}

With SIPPyException the way it is, I need to add another exception
handler everywhere:

catch(SIPPyException const)
{
  QMessageBox(QMessageBox::Critical, Error, pythonExceptionToText(), 
QMessageBox::Ok).exec();
}

If I could provide a function to call instead of just doing
throw SIPPyException(), I could throw an exception there myself
as I see fit. For example, there could be a directive

%MethodErrorHandlerCode
  throw std::runtime_error(pythonExceptionToText());
%End

which would follow the %Module directive to define the body of an
error handler function which is called instead of throw SIPPyException().

Best Regards,
Mathias


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: how to make a python instance owned by C++ without using a parent

2012-08-15 Thread Mathias . Born
On 15.08.2012, 11:05:42 Phil Thompson wrote:
 On Tue, 14 Aug 2012 23:47:51 +0200, mathias.b...@gmx.de wrote:
 Thanks for the answer. However, it appears I've not made myself
 clear enough.
 I don't want the C++ wrapper to be owned by Python; surely, I
 can achieve that with sipTransferTo. But nothing is done about the
 Python part. When I delete the wrapper in C++, the Python part it wraps
 stays alive, because its reference count is not touched. (No parent!)
 I have to manually, explicitely decrease the reference count to get
 rid of it. I'm not complaining. I get this Python object from a Python
 function, so I have to take care of it.
 
 However, the sip module already contains some code that essentially
 already would do what I want:
 
  siplib.c ===
 void sip_api_common_dtor(sipSimpleWrapper *sipSelf)
 {
 if (sipSelf != NULL  sipInterpreter != NULL)
 {
 PyObject *xtype, *xvalue, *xtb;
 
 SIP_BLOCK_THREADS
 
 /* We may be tidying up after an exception so preserve it. */
 PyErr_Fetch(xtype, xvalue, xtb);
 callPyDtor(sipSelf);
 PyErr_Restore(xtype, xvalue, xtb);
 
 sipOMRemoveObject(cppPyMap, sipSelf);
 
 /* This no longer points to anything useful. */
 clear_access_func(sipSelf);
 
 /*
  * If C/C++ has a reference (and therefore no parent) then
 remove
  it.
  * Otherwise remove the object from any parent.
  */
 if (sipCppHasRef(sipSelf))
 {
 sipResetCppHasRef(sipSelf);
 Py_DECREF(sipSelf);
 }
 else if (PyObject_TypeCheck((PyObject *)sipSelf, (PyTypeObject
 *)sipWrapper_Type))
 removeFromParent((sipWrapper *)sipSelf);
 
 SIP_UNBLOCK_THREADS
 }
 }
 =
 
 What about:
 
 if (sipCppHasRef(sipSelf))
 {
 sipResetCppHasRef(sipSelf);
 Py_DECREF(sipSelf);
 }
 
 Is there an official way for my wrapper to have the SIP_CPP_HAS_REF
 flag
 set?
 It would then automatically dispose its Python counterpart.

 I could change sipTransferTo() to do this if the owner was Py_None. At the
 moment this is undocumented behaviour. Would this be sufficient?

I believe so.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


[PyQt] sip: extend exception support

2012-08-15 Thread Mathias . Born
Phil,

sip can already propagate C++ exceptions into Python in cases
where Python calls a C++ function which throws an exception.

However, if I extend a C++ class in Python and call a corresponding
(Python-)method in C++ via the wrapper, the sip generated
wrapper code checks for a Python exception, but doesn't throw an
excpetion itself.
For example:

= code generated by sip ===
boost::optionalint sipVH_ltse_app_0(sip_gilstate_t sipGILState,PyObject 
*sipMethod,const std::string a0)
{
boost::optionalint sipRes;
PyObject *resObj = sipCallMethod(0,sipMethod,N,new 
std::string(a0),sipType_std_string,NULL);

if (!resObj || 
sipParseResult(0,sipMethod,resObj,H5,sipType_boost_optional_1800,sipRes)  0)
PyErr_Print();

Py_XDECREF(resObj);
Py_DECREF(sipMethod);

SIP_RELEASE_GIL(sipGILState)

return sipRes;
}
=

Here, PyErr_Print is called if the Python implementation of
the method raises an exception. This is fine for Qt which
cannot deal with exceptions, but in general I would find it
much more helpful if the wrapper code generated by sip
threw a C++ exception itself to signal the problem to the
caller.

Just define a class, e.g. SIPPyException (derived from
std::exception), which becomes part of the API and is always used
in such cases.
In order not to break existing code, it would only be used in
classes or methods which are annotated appropriately.
(So an additional annotation is necessary to activate this behavior.)

I believe an extension like this would make sip a lot more useful
for embedding Python into a C++ program.

Best Regards,
Mathias Born



___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: how to make a python instance owned by C++ without using a parent

2012-08-15 Thread Mathias . Born
On 15.08.2012, 18:15:55 Phil Thompson wrote:
 On Wed, 15 Aug 2012 11:55:47 +0200, mathias.b...@gmx.de wrote:
 On 15.08.2012, 11:05:42 Phil Thompson wrote:
 I could change sipTransferTo() to do this if the owner was Py_None. At
 the
 moment this is undocumented behaviour. Would this be sufficient?
 
 I believe so.

 Done in hg.

 Phil

Thanks!

Best Regards,
Mathias Born

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


Re: [PyQt] sip: how to make a python instance owned by C++ without using a parent

2012-08-14 Thread Mathias . Born
Thanks for the answer. However, it appears I've not made myself
clear enough.
I don't want the C++ wrapper to be owned by Python; surely, I
can achieve that with sipTransferTo. But nothing is done about the
Python part. When I delete the wrapper in C++, the Python part it wraps
stays alive, because its reference count is not touched. (No parent!)
I have to manually, explicitely decrease the reference count to get
rid of it. I'm not complaining. I get this Python object from a Python
function, so I have to take care of it.

However, the sip module already contains some code that essentially
already would do what I want:

 siplib.c ===
void sip_api_common_dtor(sipSimpleWrapper *sipSelf)
{
if (sipSelf != NULL  sipInterpreter != NULL)
{
PyObject *xtype, *xvalue, *xtb;

SIP_BLOCK_THREADS

/* We may be tidying up after an exception so preserve it. */
PyErr_Fetch(xtype, xvalue, xtb);
callPyDtor(sipSelf);
PyErr_Restore(xtype, xvalue, xtb);

sipOMRemoveObject(cppPyMap, sipSelf);

/* This no longer points to anything useful. */
clear_access_func(sipSelf);

/*
 * If C/C++ has a reference (and therefore no parent) then remove it.
 * Otherwise remove the object from any parent.
 */
if (sipCppHasRef(sipSelf))
{
sipResetCppHasRef(sipSelf);
Py_DECREF(sipSelf);
}
else if (PyObject_TypeCheck((PyObject *)sipSelf, (PyTypeObject 
*)sipWrapper_Type))
removeFromParent((sipWrapper *)sipSelf);

SIP_UNBLOCK_THREADS
}
}
=

What about:

if (sipCppHasRef(sipSelf))
{
sipResetCppHasRef(sipSelf);
Py_DECREF(sipSelf);
}

Is there an official way for my wrapper to have the SIP_CPP_HAS_REF flag set?
It would then automatically dispose its Python counterpart.

Best Regards,
Mathias Born



On 14.08.2012, 10:22:26 Phil Thompson wrote:
 On Mon, 13 Aug 2012 23:07:07 +0200, mathias.b...@gmx.de wrote:
 Hi,
 
 I have a C++ class Project, which I expose to Python
 via sip.
 In Python, I sub-class:
 
 class Derived(Project):
   ...
 
 In addition, there is a Python factory function which creates an
 instance of Derived and returns it:
 
 def f():
 return Derived(...)
 
 I call this function from withing C++, and feed the return
 value into sipConvertToType, in order to create a wrapper
 of type Project, so I can call methods of the returned
 Derived instance from within C++, using the wrapper.
 
 Since the Derived instance is created by Python, it is
 owned by Python.
 Is there a way to transfer ownership to C++ without using any
 additional objects? I want the Python part to stick to the
 C++ wrapper until the latter is destroyed, at which point
 the Python part should also be automatically disposed, without
 any need to micro-manage the Python part myself.

 That will happen automatically anyway so long as Derived has a virtual
 dtor. The Python object will only ever be destroyed when its reference
 count reaches 0, irrespective of the state of the C++ instance.

 In the sip sources, I can see a flag SIP_CPP_HAS_REF that
 might just achieve that, but there appears to be no official
 way to use it.

 To transfer ownership of a Python object to C++ (ie. to control whether
 the Python dealloc code calls the C++ dtor) use...

 http://www.riverbankcomputing.com/static/Docs/sip4/c_api.html#sipTransferTo

 Phil

___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt


[PyQt] sip: how to make a python instance owned by C++ without using a parent

2012-08-13 Thread Mathias . Born
Hi,

I have a C++ class Project, which I expose to Python
via sip.
In Python, I sub-class:

class Derived(Project):
  ...

In addition, there is a Python factory function which creates an
instance of Derived and returns it:

def f():
return Derived(...)

I call this function from withing C++, and feed the return
value into sipConvertToType, in order to create a wrapper
of type Project, so I can call methods of the returned
Derived instance from within C++, using the wrapper.

Since the Derived instance is created by Python, it is
owned by Python.
Is there a way to transfer ownership to C++ without using any
additional objects? I want the Python part to stick to the
C++ wrapper until the latter is destroyed, at which point
the Python part should also be automatically disposed, without
any need to micro-manage the Python part myself.

In the sip sources, I can see a flag SIP_CPP_HAS_REF that
might just achieve that, but there appears to be no official
way to use it.

Best Regards,
Mathias Born


___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt