pax_global_header00006660000000000000000000000064125777427610014534gustar00rootroot0000000000000052 comment=3c1676e9fb729f84c9d46bae0d2e65196ed73006 ros-python-qt-binding-0.2.17/000077500000000000000000000000001257774276100157775ustar00rootroot00000000000000ros-python-qt-binding-0.2.17/.gitignore000066400000000000000000000000511257774276100177630ustar00rootroot00000000000000*.pyc *~ src/python_qt_binding.egg-info/ ros-python-qt-binding-0.2.17/CHANGELOG.rst000066400000000000000000000037221257774276100200240ustar00rootroot00000000000000^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Changelog for package python_qt_binding ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 0.2.17 (2015-09-19) ------------------- * change import order of builtins to work when the 'future' package is installed in Python 2 (`#24 `_) 0.2.16 (2015-05-04) ------------------- * use qmake with QT_SELECT since qmake-qt4 is not available on all platforms (`#22 `_) 0.2.15 (2015-04-23) ------------------- * support PyQt4.11 and higher when built with configure-ng.py (`#13 `_) * __builtin__ became builtins in Python 3 (`#16 `_) 0.2.14 (2014-07-10) ------------------- * add Python_ADDITIONAL_VERSIONS and ask for specific version of PythonInterp * fix finding specific version of PythonLibs with CMake 3 (`#11 `_) * fix sip_helper to use python header dirs on OS X (`#12 `_) 0.2.13 (2014-05-07) ------------------- * fix sip arguments when path contains spaces 0.2.12 (2014-01-08) ------------------- * python 3 compatibility * fix sip bindings when paths contain spaces (`#9 `_) 0.2.11 (2013-08-21) ------------------- * allow overriding binding order * allow to release python_qt_binding as a standalone package to PyPI (`#5 `_) 0.2.10 (2013-06-06) ------------------- * refactor loadUi function to be documentable (`#2 `_) 0.2.9 (2013-04-19) ------------------ 0.2.8 (2013-01-13) ------------------ 0.2.7 (2012-12-21) ------------------ * first public release for Groovy ros-python-qt-binding-0.2.17/CMakeLists.txt000066400000000000000000000005111257774276100205340ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8.3) project(python_qt_binding) find_package(catkin REQUIRED) catkin_package(CFG_EXTRAS python_qt_binding-extras.cmake) catkin_python_setup() install(FILES cmake/shiboken_helper.cmake cmake/sip_configure.py cmake/sip_helper.cmake DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/cmake) ros-python-qt-binding-0.2.17/MANIFEST.in000066400000000000000000000000711257774276100175330ustar00rootroot00000000000000include package.xml recursive-include cmake *.cmake *.py ros-python-qt-binding-0.2.17/Makefile000066400000000000000000000011561257774276100174420ustar00rootroot00000000000000.PHONY: all setup clean_dist distro clean install upload push NAME=python_qt_binding VERSION=`./setup.py --version` all: echo "noop for debbuild" setup: echo "building version ${VERSION}" clean_dist: -rm -f MANIFEST -rm -rf dist distro: setup clean_dist python setup.py sdist push: distro python setup.py sdist register upload scp dist/${NAME}-${VERSION}.tar.gz ros@ftp-osl.osuosl.org:/home/ros/data/download.ros.org/downloads/${NAME} clean: clean_dist echo "clean" install: distro sudo checkinstall python setup.py install testsetup: echo "running ${NAME} tests" test: testsetup cd test && nosetests ros-python-qt-binding-0.2.17/cmake/000077500000000000000000000000001257774276100170575ustar00rootroot00000000000000ros-python-qt-binding-0.2.17/cmake/python_qt_binding-extras.cmake.em000066400000000000000000000003731257774276100255070ustar00rootroot00000000000000@[if DEVELSPACE]@ # location of cmake files in develspace set(python_qt_binding_EXTRAS_DIR "@(CMAKE_CURRENT_SOURCE_DIR)/cmake") @[else]@ # location of cmake files in installspace set(python_qt_binding_EXTRAS_DIR "${python_qt_binding_DIR}") @[end if]@ ros-python-qt-binding-0.2.17/cmake/shiboken_helper.cmake000066400000000000000000000112351257774276100232240ustar00rootroot00000000000000if(__PYTHON_QT_BINDING_SHIBOKEN_HELPER_INCLUDED) return() endif() set(__PYTHON_QT_BINDING_SHIBOKEN_HELPER_INCLUDED TRUE) if("${PYTHON_VERSION_MAJOR}" STREQUAL "2") set(PYTHON_SUFFIX "-python${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") elseif("${PYTHON_VERSION_MAJOR}" STREQUAL "3") if("${PYTHON_VERSION_MINOR}" STRLESS "3") set(PYTHON_SUFFIX ".cpython-${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}mu") else() set(PYTHON_SUFFIX ".cpython-${PYTHON_VERSION_MAJOR}${PYTHON_VERSION_MINOR}m") endif() else() message(FATAL_ERROR "Unknown Python version: ${PYTHON_VERSION_STRING}") endif() find_package(Shiboken) if(SHIBOKEN_LIBRARY) message("Using SHIBOKEN_LIBRARY: ${SHIBOKEN_LIBRARY}") endif() find_package(PySide) if(PYSIDE_LIBRARY) message("Using PYSIDE_LIBRARY: ${PYSIDE_LIBRARY}") endif() set(Python_ADDITIONAL_VERSIONS "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") find_package(PythonLibs "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") if(Shiboken_FOUND AND (NOT Shiboken_VERSION VERSION_LESS "1.1.0")) # starting from version 1.1.1 shiboken brings along it's own generator binary # still under Ubuntu precise it also works with shiboken 1.1.0 set(GeneratorRunner_FOUND TRUE) set(GENERATORRUNNER_BINARY ${SHIBOKEN_BINARY}) else() find_package(GeneratorRunner) endif() if(GeneratorRunner_FOUND AND PySide_FOUND AND PYTHONLIBS_FOUND) message(STATUS "Shiboken binding generator available.") set(shiboken_helper_FOUND TRUE) else() message(WARNING "Shiboken binding generator NOT available.") set(shiboken_helper_NOTFOUND TRUE) endif() macro(_shiboken_generator_command VAR GLOBAL TYPESYSTEM INCLUDE_PATH BUILD_DIR) # See ticket https://code.ros.org/trac/ros-pkg/ticket/5219 set(QT_INCLUDE_DIR_WITH_COLONS "") foreach(dir ${QT_INCLUDE_DIR}) set(QT_INCLUDE_DIR_WITH_COLONS "${QT_INCLUDE_DIR_WITH_COLONS}:${dir}") endforeach() set(${VAR} ${GENERATORRUNNER_BINARY} --generatorSet=shiboken --include-paths=${INCLUDE_PATH}:${QT_INCLUDE_DIR_WITH_COLONS} --typesystem-paths=${PYSIDE_TYPESYSTEMS} --output-directory=${BUILD_DIR} ${GLOBAL} ${TYPESYSTEM}) endmacro() # # Run the Shiboken generator. # # :param PROJECT_NAME: The name of the shiboken project is only use for # the custom command comment # :type PROJECT_NAME: string # :param GLOBAL: the SIP file # :type GLOBAL: string # :param TYPESYSTEM: the typesystem file # :type TYPESYSTEM: string # :param WORKING_DIR: the working directory # :type WORKING_DIR: string # :param GENERATED_SRCS: the generated source files # :type GENERATED_SRCS: list of strings # :param HDRS: the processed header files # :type HDRS: list of strings # :param INCLUDE_PATH: the include path # :type INCLUDE_PATH: list of strings # :param BUILD_DIR: the build directory # :type BUILD_DIR: string # function(shiboken_generator PROJECT_NAME GLOBAL TYPESYSTEM WORKING_DIR GENERATED_SRCS HDRS INCLUDE_PATH BUILD_DIR) _shiboken_generator_command(COMMAND "${GLOBAL}" "${TYPESYSTEM}" "${INCLUDE_PATH}" "${BUILD_DIR}") add_custom_command( OUTPUT ${GENERATED_SRCS} COMMAND ${COMMAND} DEPENDS ${GLOBAL} ${TYPESYSTEM} ${HDRS} WORKING_DIRECTORY ${WORKING_DIR} COMMENT "Running Shiboken generator for ${PROJECT_NAME} Python bindings..." ) endfunction() # # Add the Shiboken/PySide specific include directories. # # :param PROJECT_NAME: The namespace of the binding # :type PROJECT_NAME: string # :param QT_COMPONENTS: the Qt components # :type QT_COMPONENTS: list of strings # function(shiboken_include_directories PROJECT_NAME QT_COMPONENTS) set(shiboken_INCLUDE_DIRECTORIES ${PYTHON_INCLUDE_DIR} ${SHIBOKEN_INCLUDE_DIR} ${PYSIDE_INCLUDE_DIR} ${PYSIDE_INCLUDE_DIR}/QtCore ${PYSIDE_INCLUDE_DIR}/QtGui ) foreach(component ${QT_COMPONENTS}) set(shiboken_INCLUDE_DIRECTORIES ${shiboken_INCLUDE_DIRECTORIES} ${PYSIDE_INCLUDE_DIR}/${component}) endforeach() include_directories(${PROJECT_NAME} ${shiboken_INCLUDE_DIRECTORIES}) endfunction() # # Add the Shiboken/PySide specific link libraries. # # :param PROJECT_NAME: The target name of the binding library # :type PROJECT_NAME: string # :param QT_COMPONENTS: the Qt components # :type QT_COMPONENTS: list of strings # function(shiboken_target_link_libraries PROJECT_NAME QT_COMPONENTS) set(shiboken_LINK_LIBRARIES ${SHIBOKEN_PYTHON_LIBRARIES} ${SHIBOKEN_LIBRARY} ${PYSIDE_LIBRARY} ) foreach(component ${QT_COMPONENTS}) string(TOUPPER ${component} component) set(shiboken_LINK_LIBRARIES ${shiboken_LINK_LIBRARIES} ${QT_${component}_LIBRARY}) endforeach() target_link_libraries(${PROJECT_NAME} ${shiboken_LINK_LIBRARIES}) endfunction() ros-python-qt-binding-0.2.17/cmake/sip_configure.py000066400000000000000000000104031257774276100222630ustar00rootroot00000000000000from copy import copy import os import re import subprocess import sys import sipconfig try: from PyQt4.pyqtconfig import Configuration except ImportError: # PyQt >= 4.11 has no pyqtconfig module if built with configure-ng.py from PyQt4 import QtCore class Configuration(sipconfig.Configuration): def __init__(self): env = copy(os.environ) env['QT_SELECT'] = '4' qtconfig = subprocess.check_output( ['qmake', '-query'], env=env, universal_newlines=True) qtconfig = dict(line.split(':', 1) for line in qtconfig.splitlines()) pyqtconfig = { 'qt_archdata_dir': qtconfig['QT_INSTALL_DATA'], 'qt_data_dir': qtconfig['QT_INSTALL_DATA'], 'qt_dir': qtconfig['QT_INSTALL_PREFIX'], 'qt_inc_dir': qtconfig['QT_INSTALL_HEADERS'], 'qt_lib_dir': qtconfig['QT_INSTALL_LIBS'], 'qt_threaded': 1, 'qt_version': QtCore.QT_VERSION, 'qt_winconfig': 'shared', } sipconfig.Configuration.__init__(self, [pyqtconfig]) macros = sipconfig._default_macros.copy() macros['INCDIR_QT'] = qtconfig['QT_INSTALL_HEADERS'] macros['LIBDIR_QT'] = qtconfig['QT_INSTALL_LIBS'] macros['MOC'] = 'moc-qt4' self.set_build_macros(macros) if len(sys.argv) != 8: print('usage: %s build-dir sip-file output_dir include_dirs libs lib_dirs ldflags' % sys.argv[0]) sys.exit(1) # The SIP build folder, the SIP file, the output directory, the include directories, the libraries, the library directories and the linker flags. build_dir, sip_file, output_dir, include_dirs, libs, lib_dirs, ldflags = sys.argv[1:] # The name of the SIP build file generated by SIP and used by the build system. build_file = 'pyqtscripting.sbf' # Get the PyQt configuration information. config = Configuration() # Get the extra SIP flags needed by the imported qt module. Note that # this normally only includes those flags (-x and -t) that relate to SIP's # versioning system. try: sip_dir = config.pyqt_sip_dir sip_flags = config.pyqt_sip_flags except AttributeError: # sipconfig.Configuration does not have a pyqt_sip_dir or pyqt_sip_flags attribute sip_dir = sipconfig._pkg_config['default_sip_dir'] + '/PyQt4' sip_flags = QtCore.PYQT_CONFIGURATION['sip_flags'] try: os.makedirs(build_dir) except OSError: pass # Run SIP to generate the code. Note that we tell SIP where to find the qt # module's specification files using the -I flag. cmd = [ config.sip_bin, '-c', build_dir, '-b', os.path.join(build_dir, build_file), '-I', sip_dir, '-w' ] cmd += sip_flags.split(' ') cmd.append(sip_file) subprocess.check_call(cmd) # Create the Makefile. The QtModuleMakefile class provided by the # pyqtconfig module takes care of all the extra preprocessor, compiler and # linker flags needed by the Qt library. makefile = sipconfig.SIPModuleMakefile( dir=build_dir, configuration=config, build_file=build_file, qt=['QtCore', 'QtGui'] ) # hack to override makefile behavior which always prepend -l to libraries which is wrong for absolute paths default_platform_lib_function = sipconfig.SIPModuleMakefile.platform_lib def custom_platform_lib_function(self, clib, framework=0): if os.path.isabs(clib): return clib return default_platform_lib_function(self, clib, framework) sipconfig.SIPModuleMakefile.platform_lib = custom_platform_lib_function # split paths on whitespace # while dealing with whitespaces within the paths if they are escaped with backslashes def split_paths(paths): paths = re.split('(?<=[^\\\\]) ', paths) return paths for include_dir in split_paths(include_dirs): include_dir = include_dir.replace('\\', '') makefile.extra_include_dirs.append(include_dir) for lib in split_paths(libs): makefile.extra_libs.append(lib) for lib_dir in split_paths(lib_dirs): lib_dir = lib_dir.replace('\\', '') makefile.extra_lib_dirs.append(lib_dir) for ldflag in ldflags.split('\\ '): makefile.LFLAGS.append(ldflag) # redirect location of generated library makefile._target = '"%s"' % os.path.join(output_dir, makefile._target) # Generate the Makefile itself makefile.generate() ros-python-qt-binding-0.2.17/cmake/sip_helper.cmake000066400000000000000000000235121257774276100222160ustar00rootroot00000000000000if(__PYTHON_QT_BINDING_SIP_HELPER_INCLUDED) return() endif() set(__PYTHON_QT_BINDING_SIP_HELPER_INCLUDED TRUE) set(__PYTHON_QT_BINDING_SIP_HELPER_DIR ${CMAKE_CURRENT_LIST_DIR}) set(Python_ADDITIONAL_VERSIONS "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}") find_package(PythonInterp "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" REQUIRED) assert(PYTHON_EXECUTABLE) find_package(PythonLibs "${PYTHON_VERSION_MAJOR}.${PYTHON_VERSION_MINOR}" REQUIRED) find_program(SIP_EXECUTABLE sip) if(NOT SIP_EXECUTABLE_NOTFOUND) message(STATUS "SIP binding generator available.") set(sip_helper_FOUND TRUE) else() message(WARNING "SIP binding generator NOT available.") set(sip_helper_NOTFOUND TRUE) endif() # Provide cmake_parse_arguments() for versions of cmake before 2.8.3. if(${CMAKE_VERSION} VERSION_LESS 2.8.3) # CMAKE_PARSE_ARGUMENTS( args...) # # CMAKE_PARSE_ARGUMENTS() is intended to be used in macros or functions for # parsing the arguments given to that macro or function. # It processes the arguments and defines a set of variables which hold the # values of the respective options. # # The argument contains all options for the respective macro, # i.e. keywords which can be used when calling the macro without any value # following, like e.g. the OPTIONAL keyword of the install() command. # # The argument contains all keywords for this macro # which are followed by one value, like e.g. DESTINATION keyword of the # install() command. # # The argument contains all keywords for this macro # which can be followed by more than one value, like e.g. the TARGETS or # FILES keywords of the install() command. # # When done, CMAKE_PARSE_ARGUMENTS() will have defined for each of the # keywords listed in , and # a variable composed of the given # followed by "_" and the name of the respective keyword. # These variables will then hold the respective value from the argument list. # For the keywords this will be TRUE or FALSE. # # All remaining arguments are collected in a variable # _UNPARSED_ARGUMENTS, this can be checked afterwards to see whether # your macro was called with unrecognized parameters. # # As an example here a my_install() macro, which takes similar arguments as the # real install() command: # # function(MY_INSTALL) # set(options OPTIONAL FAST) # set(oneValueArgs DESTINATION RENAME) # set(multiValueArgs TARGETS CONFIGURATIONS) # cmake_parse_arguments(MY_INSTALL "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN} ) # ... # # Assume my_install() has been called like this: # my_install(TARGETS foo bar DESTINATION bin OPTIONAL blub) # # After the cmake_parse_arguments() call the macro will have set the following # variables: # MY_INSTALL_OPTIONAL = TRUE # MY_INSTALL_FAST = FALSE (this option was not used when calling my_install() # MY_INSTALL_DESTINATION = "bin" # MY_INSTALL_RENAME = "" (was not used) # MY_INSTALL_TARGETS = "foo;bar" # MY_INSTALL_CONFIGURATIONS = "" (was not used) # MY_INSTALL_UNPARSED_ARGUMENTS = "blub" (no value expected after "OPTIONAL" # # You can the continue and process these variables. # # Keywords terminate lists of values, e.g. if directly after a one_value_keyword # another recognized keyword follows, this is interpreted as the beginning of # the new option. # E.g. my_install(TARGETS foo DESTINATION OPTIONAL) would result in # MY_INSTALL_DESTINATION set to "OPTIONAL", but MY_INSTALL_DESTINATION would # be empty and MY_INSTALL_OPTIONAL would be set to TRUE therefor. #============================================================================= # Copyright 2010 Alexander Neundorf # # Distributed under the OSI-approved BSD License (the "License"); # see accompanying file Copyright.txt for details. # # This software is distributed WITHOUT ANY WARRANTY; without even the # implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # See the License for more information. #============================================================================= # (To distribute this file outside of CMake, substitute the full # License text for the above reference.) function(CMAKE_PARSE_ARGUMENTS prefix _optionNames _singleArgNames _multiArgNames) # first set all result variables to empty/FALSE foreach(arg_name ${_singleArgNames} ${_multiArgNames}) set(${prefix}_${arg_name}) endforeach(arg_name) foreach(option ${_optionNames}) set(${prefix}_${option} FALSE) endforeach(option) set(${prefix}_UNPARSED_ARGUMENTS) set(insideValues FALSE) set(currentArgName) # now iterate over all arguments and fill the result variables foreach(currentArg ${ARGN}) list(FIND _optionNames "${currentArg}" optionIndex) # ... then this marks the end of the arguments belonging to this keyword list(FIND _singleArgNames "${currentArg}" singleArgIndex) # ... then this marks the end of the arguments belonging to this keyword list(FIND _multiArgNames "${currentArg}" multiArgIndex) # ... then this marks the end of the arguments belonging to this keyword if(${optionIndex} EQUAL -1 AND ${singleArgIndex} EQUAL -1 AND ${multiArgIndex} EQUAL -1) if(insideValues) if("${insideValues}" STREQUAL "SINGLE") set(${prefix}_${currentArgName} ${currentArg}) set(insideValues FALSE) elseif("${insideValues}" STREQUAL "MULTI") list(APPEND ${prefix}_${currentArgName} ${currentArg}) endif() else(insideValues) list(APPEND ${prefix}_UNPARSED_ARGUMENTS ${currentArg}) endif(insideValues) else() if(NOT ${optionIndex} EQUAL -1) set(${prefix}_${currentArg} TRUE) set(insideValues FALSE) elseif(NOT ${singleArgIndex} EQUAL -1) set(currentArgName ${currentArg}) set(${prefix}_${currentArgName}) set(insideValues "SINGLE") elseif(NOT ${multiArgIndex} EQUAL -1) set(currentArgName ${currentArg}) set(${prefix}_${currentArgName}) set(insideValues "MULTI") endif() endif() endforeach(currentArg) # propagate the result variables to the caller: foreach(arg_name ${_singleArgNames} ${_multiArgNames} ${_optionNames}) set(${prefix}_${arg_name} ${${prefix}_${arg_name}} PARENT_SCOPE) endforeach(arg_name) set(${prefix}_UNPARSED_ARGUMENTS ${${prefix}_UNPARSED_ARGUMENTS} PARENT_SCOPE) endfunction(CMAKE_PARSE_ARGUMENTS _options _singleArgs _multiArgs) endif() # # Run the SIP generator and compile the generated code into a library. # # .. note:: The target lib${PROJECT_NAME} is created. # # :param PROJECT_NAME: The name of the sip project # :type PROJECT_NAME: string # :param SIP_FILE: the SIP file to be processed # :type SIP_FILE: string # # The following options can be used to override the default behavior: # SIP_CONFIGURE: the used configure script for SIP # (default: sip_configure.py in the same folder as this file) # SOURCE_DIR: the source dir (default: ${PROJECT_SOURCE_DIR}/src) # LIBRARY_DIR: the library dir (default: ${PROJECT_SOURCE_DIR}/src) # BINARY_DIR: the binary dir (default: ${PROJECT_BINARY_DIR}) # # The following keywords arguments can be used to specify: # DEPENDS: depends for the custom command # (should list all sip and header files) # DEPENDENCIES: target dependencies # (should list the library for which SIP generates the bindings) # function(build_sip_binding PROJECT_NAME SIP_FILE) cmake_parse_arguments(sip "" "SIP_CONFIGURE;SOURCE_DIR;LIBRARY_DIR;BINARY_DIR" "DEPENDS;DEPENDENCIES" ${ARGN}) if(sip_UNPARSED_ARGUMENTS) message(WARNING "build_sip_binding(${PROJECT_NAME}) called with unused arguments: ${sip_UNPARSED_ARGUMENTS}") endif() # set default values for optional arguments if(NOT sip_SIP_CONFIGURE) # default to sip_configure.py in this directory set(sip_SIP_CONFIGURE ${__PYTHON_QT_BINDING_SIP_HELPER_DIR}/sip_configure.py) endif() if(NOT sip_SOURCE_DIR) set(sip_SOURCE_DIR ${PROJECT_SOURCE_DIR}/src) endif() if(NOT sip_LIBRARY_DIR) set(sip_LIBRARY_DIR ${PROJECT_SOURCE_DIR}/lib) endif() if(NOT sip_BINARY_DIR) set(sip_BINARY_DIR ${PROJECT_BINARY_DIR}) endif() set(SIP_BUILD_DIR ${sip_BINARY_DIR}/sip/${PROJECT_NAME}) set(INCLUDE_DIRS ${${PROJECT_NAME}_INCLUDE_DIRS} ${PYTHON_INCLUDE_DIRS}) set(LIBRARIES ${${PROJECT_NAME}_LIBRARIES}) set(LIBRARY_DIRS ${${PROJECT_NAME}_LIBRARY_DIRS}) set(LDFLAGS_OTHER ${${PROJECT_NAME}_LDFLAGS_OTHER}) add_custom_command( OUTPUT ${SIP_BUILD_DIR}/Makefile COMMAND ${PYTHON_EXECUTABLE} ${sip_SIP_CONFIGURE} ${SIP_BUILD_DIR} ${SIP_FILE} ${sip_LIBRARY_DIR} \"${INCLUDE_DIRS}\" \"${LIBRARIES}\" \"${LIBRARY_DIRS}\" \"${LDFLAGS_OTHER}\" DEPENDS ${sip_SIP_CONFIGURE} ${SIP_FILE} ${sip_DEPENDS} WORKING_DIRECTORY ${sip_SOURCE_DIR} COMMENT "Running SIP generator for ${PROJECT_NAME} Python bindings..." ) if(NOT EXISTS "${sip_LIBRARY_DIR}") file(MAKE_DIRECTORY ${sip_LIBRARY_DIR}) endif() add_custom_command( OUTPUT ${sip_LIBRARY_DIR}/lib${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX} COMMAND make DEPENDS ${SIP_BUILD_DIR}/Makefile WORKING_DIRECTORY ${SIP_BUILD_DIR} COMMENT "Compiling generated code for ${PROJECT_NAME} Python bindings..." ) add_custom_target(lib${PROJECT_NAME} ALL DEPENDS ${sip_LIBRARY_DIR}/lib${PROJECT_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX} COMMENT "Meta target for ${PROJECT_NAME} Python bindings..." ) add_dependencies(lib${PROJECT_NAME} ${sip_DEPENDENCIES}) endfunction() ros-python-qt-binding-0.2.17/package.xml000066400000000000000000000023241257774276100201150ustar00rootroot00000000000000 python_qt_binding 0.2.17 This stack provides Python bindings for Qt. There are two providers: pyside and pyqt. PySide is released under the LGPL. PyQt is released under the GPL. Both the bindings and tools to build bindings are included from each available provider. For PySide, it is called "Shiboken". For PyQt, this is called "SIP". Also provided is adapter code to make the user's Python code independent of which binding provider was actually used which makes it very easy to switch between these. Dirk Thomas BSD LGPL GPL http://ros.org/wiki/python_qt_binding Dave Hershberger Dorian Scholz Dirk Thomas catkin rosbuild qt4-qmake python-qt-bindings python-qt-bindings ros-python-qt-binding-0.2.17/setup.py000077500000000000000000000032351257774276100175170ustar00rootroot00000000000000#!/usr/bin/env python try: from setuptools import setup except ImportError: from distutils.core import setup try: from catkin_pkg.python_setup import generate_distutils_setup d = generate_distutils_setup() except ImportError: # extract information from package.xml manually when catkin_pkg is unavailable from xml.etree import ElementTree tree = ElementTree.parse('package.xml') root = tree.getroot() d = { 'name': root.find('./name').text, 'version': root.find('./version').text, 'maintainer': root.findall('./maintainer')[0].text, 'maintainer_email': root.findall('./maintainer')[0].attrib['email'], 'license': ', '.join([x.text for x in root.findall('./license')]), 'url': root.findall('./url')[0].text, 'author': ', '.join([x.text for x in root.findall('./author')]), } description = root.find('./description').text.strip() if len(description) <= 200: d['description'] = description else: d['description'] = description[:197] + '...' d['long_description'] = description d.update({ 'packages': [d['name']], 'package_dir': {'': 'src'}, 'classifiers': [ 'Development Status :: 5 - Production/Stable', 'Intended Audience :: Developers', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Topic :: Software Development :: Libraries :: Python Modules', 'License :: OSI Approved :: BSD License', 'License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)', 'License :: OSI Approved :: GNU General Public License (GPL)', ], }) setup(**d) ros-python-qt-binding-0.2.17/src/000077500000000000000000000000001257774276100165665ustar00rootroot00000000000000ros-python-qt-binding-0.2.17/src/python_qt_binding/000077500000000000000000000000001257774276100223055ustar00rootroot00000000000000ros-python-qt-binding-0.2.17/src/python_qt_binding/QtBindingHelper.py000066400000000000000000000036601257774276100257030ustar00rootroot00000000000000#!/usr/bin/env python # Copyright (c) 2011, Dirk Thomas, Dorian Scholz, TU Darmstadt # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of the TU Darmstadt nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from __future__ import print_function print('Deprecation warning: the "python_qt_binding.QtBindingHelper" module is deprecated and will be removed in the near future.') print('Replace your usage of QtBindingHelper with import statements like:') print(' from python_qt_binding.QtCore import QObject') print(' from python_qt_binding import QtGui, loadUi') ros-python-qt-binding-0.2.17/src/python_qt_binding/__init__.py000066400000000000000000000053421257774276100244220ustar00rootroot00000000000000#!/usr/bin/env python # Copyright (c) 2011, Dirk Thomas, Dorian Scholz, TU Darmstadt # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of the TU Darmstadt nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. """ Abstraction for different Python Qt bindings. Supported Python Qt bindings are PyQt4 and PySide. The Qt modules can be imported like this: from python_qt_binding.QtCore import QObject from python_qt_binding import QtGui, loadUi The name of the selected binding is available in QT_BINDING. The version of the selected binding is available in QT_BINDING_VERSION. All available Qt modules are listed in QT_BINDING_MODULES. The default binding order ('pyqt', 'pyside') can be overridden with a SELECT_QT_BINDING_ORDER attribute on sys: setattr(sys, 'SELECT_QT_BINDING_ORDER', [FIRST_NAME, NEXT_NAME, ..]) A specific binding can be selected with a SELECT_QT_BINDING attribute on sys: setattr(sys, 'SELECT_QT_BINDING', MY_BINDING_NAME) """ import sys from .binding_helper import loadUi, QT_BINDING, QT_BINDING_MODULES, QT_BINDING_VERSION # @UnusedImport # register all binding modules as sub modules of this package (python_qt_binding) for easy importing for module_name, module in QT_BINDING_MODULES.items(): sys.modules[__name__ + '.' + module_name] = module setattr(sys.modules[__name__], module_name, module) del module_name del module del sys ros-python-qt-binding-0.2.17/src/python_qt_binding/binding_helper.py000066400000000000000000000232131257774276100256310ustar00rootroot00000000000000#!/usr/bin/env python # Copyright (c) 2011, Dirk Thomas, Dorian Scholz, TU Darmstadt # All rights reserved. # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions # are met: # # * Redistributions of source code must retain the above copyright # notice, this list of conditions and the following disclaimer. # * Redistributions in binary form must reproduce the above # copyright notice, this list of conditions and the following # disclaimer in the documentation and/or other materials provided # with the distribution. # * Neither the name of the TU Darmstadt nor the names of its # contributors may be used to endorse or promote products derived # from this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE # COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. try: import __builtin__ as builtins except ImportError: # since the 'future' package provides a 'builtins' module in Python 2 # this must not be checked second import builtins import os import sys QT_BINDING = None QT_BINDING_MODULES = {} QT_BINDING_VERSION = None def _select_qt_binding(binding_name=None, binding_order=None): global QT_BINDING, QT_BINDING_VERSION # order of default bindings can be changed here DEFAULT_BINDING_ORDER = ['pyqt', 'pyside'] binding_order = binding_order or DEFAULT_BINDING_ORDER # determine binding preference if binding_name: if binding_name not in binding_order: raise ImportError("Qt binding '%s' is unknown" % binding_name) binding_order = [binding_name] required_modules = [ 'QtCore', 'QtGui' ] optional_modules = [ 'QtDeclarative', 'QtMultimedia', 'QtNetwork', 'QtOpenGL', 'QtOpenVG', 'QtScript', 'QtScriptTools' 'QtSql', 'QtSvg', 'QtWebKit', 'QtXml', 'QtXmlPatterns', ] # try to load preferred bindings error_msgs = [] for binding_name in binding_order: try: binding_loader = getattr(sys.modules[__name__], '_load_%s' % binding_name, None) if binding_loader: QT_BINDING_VERSION = binding_loader(required_modules, optional_modules) QT_BINDING = binding_name break else: error_msgs.append(" Binding loader '_load_%s' not found." % binding_name) except ImportError as e: error_msgs.append(" ImportError for '%s': %s" % (binding_name, e)) if not QT_BINDING: raise ImportError("Could not find Qt binding (looked for: %s):\n%s" % (', '.join(["'%s'" % b for b in binding_order]), '\n'.join(error_msgs))) def _register_binding_module(module_name, module): # register module using only its own name (TODO: legacy compatibility, remove when possible) sys.modules[module_name] = module # add module to the binding modules QT_BINDING_MODULES[module_name] = module def _named_import(name): parts = name.split('.') assert(len(parts) >= 2) module = builtins.__import__(name) for m in parts[1:]: module = module.__dict__[m] module_name = parts[-1] _register_binding_module(module_name, module) def _named_optional_import(name): try: _named_import(name) except ImportError: pass def _load_pyqt(required_modules, optional_modules): # set environment variable QT_API for matplotlib os.environ['QT_API'] = 'pyqt' # select PyQt4 API, see http://pyqt.sourceforge.net/Docs/PyQt4/incompatible_apis.html import sip try: sip.setapi('QDate', 2) sip.setapi('QDateTime', 2) sip.setapi('QString', 2) sip.setapi('QTextStream', 2) sip.setapi('QTime', 2) sip.setapi('QUrl', 2) sip.setapi('QVariant', 2) except ValueError as e: raise RuntimeError('Could not set API version (%s): did you import PyQt4 directly?' % e) # register required and optional PyQt4 modules for module_name in required_modules: _named_import('PyQt4.%s' % module_name) for module_name in optional_modules: _named_optional_import('PyQt4.%s' % module_name) # set some names for compatibility with PySide sys.modules['QtCore'].Signal = sys.modules['QtCore'].pyqtSignal sys.modules['QtCore'].Slot = sys.modules['QtCore'].pyqtSlot sys.modules['QtCore'].Property = sys.modules['QtCore'].pyqtProperty # try to register PyQt4.Qwt5 module try: import PyQt4.Qwt5 _register_binding_module('Qwt', PyQt4.Qwt5) except ImportError: pass global _loadUi def _loadUi(uifile, baseinstance=None, custom_widgets_=None): from PyQt4 import uic return uic.loadUi(uifile, baseinstance=baseinstance) # override specific function to improve compatibility between different bindings from QtGui import QFileDialog QFileDialog.getOpenFileName = QFileDialog.getOpenFileNameAndFilter QFileDialog.getSaveFileName = QFileDialog.getSaveFileNameAndFilter import PyQt4.QtCore return PyQt4.QtCore.PYQT_VERSION_STR def _load_pyside(required_modules, optional_modules): # set environment variable QT_API for matplotlib os.environ['QT_API'] = 'pyside' # register required and optional PySide modules for module_name in required_modules: _named_import('PySide.%s' % module_name) for module_name in optional_modules: _named_optional_import('PySide.%s' % module_name) # set some names for compatibility with PyQt4 sys.modules['QtCore'].pyqtSignal = sys.modules['QtCore'].Signal sys.modules['QtCore'].pyqtSlot = sys.modules['QtCore'].Slot sys.modules['QtCore'].pyqtProperty = sys.modules['QtCore'].Property # try to register PySideQwt module try: import PySideQwt _register_binding_module('Qwt', PySideQwt) except ImportError: pass global _loadUi def _loadUi(uifile, baseinstance=None, custom_widgets=None): from PySide.QtUiTools import QUiLoader from PySide.QtCore import QMetaObject class CustomUiLoader(QUiLoader): class_aliases = { 'Line': 'QFrame', } def __init__(self, baseinstance=None, custom_widgets=None): super(CustomUiLoader, self).__init__(baseinstance) self._base_instance = baseinstance self._custom_widgets = custom_widgets or {} def createWidget(self, class_name, parent=None, name=''): # don't create the top-level widget, if a base instance is set if self._base_instance and not parent: return self._base_instance if class_name in self._custom_widgets: widget = self._custom_widgets[class_name](parent) else: widget = QUiLoader.createWidget(self, class_name, parent, name) if str(type(widget)).find(self.class_aliases.get(class_name, class_name)) < 0: sys.modules['QtCore'].qDebug(str('PySide.loadUi(): could not find widget class "%s", defaulting to "%s"' % (class_name, type(widget)))) if self._base_instance: setattr(self._base_instance, name, widget) return widget loader = CustomUiLoader(baseinstance, custom_widgets) # instead of passing the custom widgets, they should be registered using QUiLoader.registerCustomWidget(), # but this does not work in PySide 1.0.6: it simply segfaults... #loader = CustomUiLoader(baseinstance) #custom_widgets = custom_widgets or {} #for custom_widget in custom_widgets.values(): # loader.registerCustomWidget(custom_widget) ui = loader.load(uifile) QMetaObject.connectSlotsByName(ui) return ui import PySide return PySide.__version__ def loadUi(uifile, baseinstance=None, custom_widgets=None): """ @type uifile: str @param uifile: Absolute path of .ui file @type baseinstance: QWidget @param baseinstance: the optional instance of the Qt base class. If specified then the user interface is created in it. Otherwise a new instance of the base class is automatically created. @type custom_widgets: dict of {str:QWidget} @param custom_widgets: Class name and type of the custom classes used in uifile if any. This can be None if no custom class is in use. (Note: this is only necessary for PySide, see http://answers.ros.org/question/56382/what-does-python_qt_bindingloaduis-3rd-arg-do-in-pyqt-binding/ for more information) """ return _loadUi(uifile, baseinstance, custom_widgets) _select_qt_binding( getattr(sys, 'SELECT_QT_BINDING', None), getattr(sys, 'SELECT_QT_BINDING_ORDER', None), )