Russian Qt Forum

Программирование => Python => Тема начата: Mixolap от Сентябрь 13, 2007, 13:27



Название: Использование sip3.7 для обертки своих классов на основе QT4.3
Отправлено: Mixolap от Сентябрь 13, 2007, 13:27
Написал небольшое руководство по использованию sip. Прошу оценить полезность.

Использование sip4.7 для обертки своих классов на основе QT4.3

Данное руководство описывает обертку простейшего класса на основе QLabel для его дальнейшего использования в проектах Python.
При написании руководства использовались следующие продукты:
QT-4.3.1       (www.trolltech.com)
PyQT-4.3       (www.riverbankcomputing.co.uk)
python-2.5     (www.python.org)
sip-4.7        (www.riverbankcomputing.co.uk)

Все продукты OpenSource.

Примеры разрабатывались и тестировались под ОС Fedora 7.

Содержание статьи:
1. Написание класса Hello наследуемого от QLabel;
2. Написание обертки класса Hello;
3. Написание скрипта конфигурации сборки модуля python;
4. Сборка и установка модуля Hello;
5. Тестовый пример.

1. Написание класса Hello наследуемого от QLabel

Создаем заголовочный файл hello.h для класса Hello следующего вида:
Код:
#ifndef HELLO_H
#define HELLO_H

#if defined(Q_WS_WIN)
// директивы импорта/экспорта для создания dll для Windows
#if defined(HELLO_DLL)
#define HELLO_EXPORT       __declspec(dllimport)
#elif defined(HELLO_MAKE_DLL)
#define HELLO_EXPORT       __declspec(dllexport)
#endif

#endif

#if !defined(HELLO_EXPORT)
#define HELLO_EXPORT
#endif


#include <QLabel>
#include <QWidget>
#include <QString>

class HELLO_EXPORT Hello : public QLabel {
    Q_OBJECT
public:
    Hello(QWidget *parent, const char *name = 0);

};


#endif


Создаем файл hello.cpp, в котором реализация конструктора класса:
Код:
#include "hello.h"

Hello::Hello(QWidget *parent, const char *name)
: QLabel(parent)
{
setText("hello from Qt");
}
Создаем файл проекта QT:
Код:
TEMPLATE = lib    # в результате компиляции необходимо получить динамическую библиотеку
HEADERS=hello.h   # подключаем заголовочный файл класса Hello
SOURCES=hello.cpp # подключаем файл исходника класса Hello
Теперь компилируем библиотеку командами:
qmake
make

В результате получим библиотеку
libhello.so.1.0.0
и три ссылки на нее:
libhello.so
libhello.so.1
libhello.so.1.0

Библиотека для динамического подключения класса Hello готова.

2. Написание обертки класса Hello.

Создаем файл обертки hello.sip
Код:
%Module hello 0 // указываем наименование модуля hello и номер версии 0
// подключаем модули ядра и графического интерфейса
%Import QtCore/QtCoremod.sip 
%Import QtGui/QtGuimod.sip


class Hello : QLabel {

%TypeHeaderCode
#include "hello.h"  // вписываем сюда заголовочный файл класса Hello
%End

public:
    Hello(QWidget * /TransferThis/, const char * = 0);   //описываем конструктор класса

};
Примечание TransferThis необходимо, чтобы в дальнейшем при использовании класса, сборщик мусора Python корректно удалял объект.

3. Написание скрипта конфигурации сборки модуля python.

Создаем скрипт конфигурации configure.py:
Код:
import os
import sipconfig
from PyQt4 import pyqtconfig   # импортируем модуль конфигурации Qt

build_file = "hello.sbf"   # используется для сборки


config = pyqtconfig.Configuration()

qt_sip_flags = config.pyqt_sip_flags   # флаги конфигурации sip для PyQt
# Run SIP to generate the code.  Note that we tell SIP where to find the qt
# module's specification files using the -I flag.
# запускаем sip для генерации кода обертки, на вход файл сборки, путь к директории sip, флаги sip (из настроек PyQt), файл обертки класса hello
os.system(" ".join([config.sip_bin, "-c", ".", "-b", build_file, "-I", config.pyqt_sip_dir, qt_sip_flags, "hello.sip"]))

# переходим к созданию файла конфигурации сборки
installs = []

installs.append(["hello.sip", os.path.join(config.pyqt_sip_dir, "hello")])

installs.append(["helloconfig.py", config.pyqt_sip_dir])

# создание файла сборки Makefile модуля hello
makefile = pyqtconfig.QtGuiModuleMakefile(
    configuration=config,
    build_file=build_file,
    installs=installs
)

# добавляем путь с библиотекой (текущая директория) и саму библиотеку к файлу сборки
# (ВНИМАНИЕ: никаких префиксов типа lib и суффиксов типа dll не указываем)
makefile.extra_lib_dirs.append(".")
makefile.extra_libs.append("hello")

# генерируем Makefile
makefile.generate()

# далее создаем конфигурационный модуль
# указываем флаги конфигурации sip 
content = {
    "hello_sip_dir":    config.pyqt_sip_dir,
    "hello_sip_flags":  qt_sip_flags
}

# создаем конфигурационный модуль helloconfig.py из шаблона helloconfig.py.in
sipconfig.create_config_module("helloconfig.py", "helloconfig.py.in", content)
Шаблон создания конфигурационного модуля helloconfig.py.in (был взят из руководства по sip с www.riverbankcomputing.co.uk):
Код:
from PyQt4 import pyqtconfig

# These are installation specific values created when Hello was configured.
# The following line will be replaced when this template is used to create
# the final configuration module.
# @SIP_CONFIGURATION@

class Configuration(pyqtconfig.Configuration):
    """The class that represents Hello configuration values.
    """
    def __init__(self, sub_cfg=None):
        """Initialise an instance of the class.

        sub_cfg is the list of sub-class configurations.  It should be None
        when called normally.
        """
        # This is all standard code to be copied verbatim except for the
        # name of the module containing the super-class.
        if sub_cfg:
            cfg = sub_cfg
        else:
            cfg = []

        cfg.append(_pkg_config)

        pyqtconfig.Configuration.__init__(self, cfg)

class HelloModuleMakefile(pyqtconfig.QtGuiModuleMakefile):
    """The Makefile class for modules that %Import hello.
    """
    def finalise(self):
        """Finalise the macros.
        """
        # Make sure our C++ library is linked.
        self.extra_libs.append("hello")

        # Let the super-class do what it needs to.
        pyqtconfig.QtGuiModuleMakefile.finalise(self)


4. Сборка и установка модуля Hello.

Собираем и устанавливаем модуль следующими командами:
python configure.py
make
sudo make install


5. Тестовый пример, показывающий результат проделанной работы (файл test.py):
Код:
import hello  # импортируем созданный модуль
import sys
from PyQt4 import QtGui

if __name__=="__main__":
app = QtGui.QApplication(sys.argv)
mainwindow = hello.Hello(None) # создаем объект нашего класса Hello
mainwindow.show()              # показываем его экране
sys.exit(app.exec_())



Название: Re: Использование sip3.7 для обертки своих классов на основе QT4.3
Отправлено: Tonal от Сентябрь 14, 2007, 10:25
Круть!
Спасибо!


Название: Re: Использование sip3.7 для обертки своих классов на основе QT4.3
Отправлено: Borbaris161 от Апрель 15, 2015, 14:26
Не много не понятен этап написания sip файла....где чем и как его писать....точнее как понятно из текста...как он создается??????


Название: Re: Использование sip3.7 для обертки своих классов на основе QT4.3
Отправлено: gil9red от Апрель 15, 2015, 14:28
Не много не понятен этап написания sip файла....где чем и как его писать....точнее как понятно из текста...как он создается??????

блокнотом или другим любимым текстовым редактором :)


Название: Re: Использование sip3.7 для обертки своих классо&#
Отправлено: Borbaris161 от Апрель 15, 2015, 14:47
Это я уже понял....вопрос такой ...когда собираю проект , то не совсем такие  библиотеки собираются hello.o, libhello.a, moc_hello.o Не понятно=)))))))) и не понятно где команды прописывать make sudo make install


Название: Re: Использование sip3.7 для обертки своих классо&#
Отправлено: Nimbus от Апрель 15, 2015, 17:14
и не понятно где команды прописывать make sudo make install
В переменную QMAKE_EXTRA_COMPILERS в qmake проекте