Evgenii Legotckoi
Evgenii LegotckoiШілде 18, 2018, 3:14 Т.Ж.

Өзіңіздің Python байланыстыруларыңызды жазыңыз

Бүгін біз өзіңіздің жобаңызға байланыстыруларды қалай жасауға болатынын қарастырамыз.

Qt компаниясы Python-ға арналған Qt құрамына сіздің негізгі байланыстыру құралы Shiboken де кіретінін қуана хабарлайды.

Төмендегі материалды оқып шығыңыз және сіз қарапайым C++ кітапханасы үшін Python байланыстарын жасау туралы түсінік аласыз.

Бұл сізді өзіңіздің жеке кітапханаларыңызбен бірдей істеуге шақырады деп үміттенеміз.

Кез келген Qt жобасы сияқты, біз Shiboken туралы мақалаларды беруге қуаныштымыз, осылайша оның барлығына түсінікті жақсартамыз.

Кітапхана үлгісі

Бұл жазбаның негізгі мақсаты - Universe деп аталатын аздап мағынасыз пайдаланушы кітапханасын пайдалану. Ол екі сыныпты ұсынады: балмұздақ (балмұздақ) және жүк көлігі (жүк көлігі).


Балмұздақ дәмімен сипатталады, ал Жүк машинасы маңайдағы балаларға балмұздақ жеткізу құралы ретінде қызмет етеді. Өте қарапайым.

Біз бұл сыныптарды Python ішінде пайдаланғымыз келеді. Қолданылатын жағдай қосымша балмұздақ дәмін қосу немесе балмұздақ жеткізудің сәтті болғанын тексеру болып табылады. Қарапайым тілмен айтқанда, біз балмұздақ пен жүк көлігіне арналған Python байланыстыруларын ұсынғымыз келеді, осылайша біз оларды Python сценарийінде пайдалана аламыз.

Біз қысқаша болу үшін кейбір бөліктерді өткізіп жібереміз, бірақ сіз толық бастапқы кодты алу үшін репозиторийді тексере аласыз. Репозиторийге сілтеме pyside-setup/examples/samplebinding .

C++ кітапханасы

Алдымен, Icecream тақырып файлын қарастырайық

class Icecream
{
public:
    Icecream(const std::string &flavor);
    virtual Icecream *clone();
    virtual ~Icecream();
    virtual const std::string getFlavor();

private:
    std::string m_flavor;
};

және жүк көлігі тақырыбы файлы

class Truck {
public:
    Truck(bool leaveOnDestruction = false);
    Truck(const Truck &other);
    Truck& operator=(const Truck &other);
    ~Truck();

    void addIcecreamFlavor(Icecream *icecream);
    void printAvailableFlavors() const;

    bool deliver() const;
    void arrive() const;
    void leave() const;

    void setLeaveOnDestruction(bool value);
    void setArrivalMessage(const std::string &message);

private:
    void clearFlavors();

    bool m_leaveOnDestruction = false;
    std::string m_arrivalMessage = "A new icecream truck has arrived!\n";
    std::vector m_flavors;
};

Көптеген API интерфейстерін түсіну оңай болуы керек, бірақ біз маңызды бөліктерді қорытындылаймыз:

  • Балмұздақ полиморфты түрі болып табылады және оны қайта анықтауға арналған
  • getFlavor() нақты алынған түрге байланысты дәмді қайтарады
  • Жүк көлігі өзіне тиесілі балмұздақ нысандарының векторын сақтайды, оны addIcecreamFlavor() арқылы қосуға болады.
  • Жүк көлігінің келуі туралы хабарды setArrivalMessage() арқылы конфигурациялауға болады.
  • deliver() бізге «балмұздақпен» жеткізу сәтті болды ма, жоқ па дейді

Шибокен типті жүйе

Shiboken-ті API туралы хабардар ету үшін бізге байланыстырулар қажет, ол үшін бізді қызықтыратын түрлерді қамтитын тақырып файлын жасаймыз:

#ifndef BINDINGS_H
#define BINDINGS_H
#include "icecream.h"
#include "truck.h"
#endif // BINDINGS_H

Сонымен қатар, shiboken C++ және Python түрлері арасындағы байланысты анықтайтын XML типтік жүйе файлын қажет етеді:

<?xml version="1.0"?>
<typesystem package="Universe">
    <primitive-type name="bool"/>
    <primitive-type name="std::string"/>
    <object-type name="Icecream">
        <modify-function signature="clone()">
            <modify-argument index="0">
                <define-ownership owner="c++"/>
            </modify-argument>
        </modify-function>
    </object-type>
    <value-type name="Truck">
        <modify-function signature="addIcecreamFlavor(Icecream*)">
            <modify-argument index="1">
                <define-ownership owner="c++"/>
            </modify-argument>
        </modify-function>
    </value-type>
</typesystem>

Бірінші назар аударатын маңызды нәрсе, біз «bool» және «std::string» қарабайыр типтер ретінде жариялаймыз. Кейбір C++ әдістері оларды параметр/қайтару түрлері ретінде пайдаланады, сондықтан шибокен олар туралы білуі керек. Содан кейін ол C++ және Python арасында сәйкес түрлендіру кодын жасай алады.

C++ қарабайыр түрлерінің көпшілігі шибокен арқылы ешқандай қосымша кодты қажет етпестен өңделеді. Содан кейін біз жоғарыдағы екі сыныпты жариялаймыз. Олардың бірі «объект-тип» (объект-тип), екіншісі «мән түрі» (құндылық-объект) ретінде.

Негізгі айырмашылығы, «нысан түрі» құрылған кодта көрсеткіш ретінде беріледі, ал «мән түрі» көшіріледі (мән семантикасы).

Жүйе түрінің файлында сынып атауларын орнату арқылы shiboken автоматты түрде сыныптарда жарияланған барлық әдістер үшін байланыстыруларды жасауға әрекет жасайды, сондықтан барлық әдіс атауларын қолмен көрсетудің қажеті жоқ...

Мүмкіндікті қандай да бір жолмен өзгерткіңіз келмесе, бұл бізді келесі тақырыпқа, Иелік ережелеріне әкеледі.

Шибокен Python кодында орналастырылған C++ нысандарын босатуға кім жауапты екенін сиқырлы түрде таба алмайды.

Көптеген жағдайлар болуы мүмкін: Python нысанына сілтемелер саны нөлге тең болғанда Python C++ жадын босатуы керек немесе Python C++ нысанын C++ кітапханасының бір нүктесінде жойылады деп есептей отырып, ешқашан жоймауы керек. Немесе бұл басқа нысанның ата-анасы болуы мүмкін (мысалы, QWidgets сияқты). Біздің жағдайда clone() әдісі тек C++ кітапханасының ішінде шақырылады және біз C++ коды клондалған нысанның жадын босатуға қамқорлық жасайды деп есептейміз.

addIcecreamFlavor() функциясына келетін болсақ, біз Жүк машинасының Icecream нысанында тұратынын және Жүк көлігі жойылғаннан кейін бірден жойылатынын білеміз. Сонымен, иелік «c++» болып орнатылды.

Егер біз иелік ережелерін көрсетпесек, сәйкес Python атаулары қолданыс аясынан шыққанда C++ нысандары жойылатын еді.

Ассамблея

Теңшелетін Universe кітапханасын құру және одан кейін ол үшін байланыстыруларды жасау үшін біз жақсы құжатталған, негізінен жалпы CMakeLists.txt файлын береміз, оны өз кітапханаларыңыз үшін қайта пайдалануға болады.

Ол негізінен жобаны орнату үшін «cmake.» деп қоңырау шалумен аяқталады, содан кейін таңдаған құралдар тізбегімен құрастырыңыз («(N) Makefiles генераторын ұсынамыз).

Жобаны жасау нәтижесінде сіз екі ортақ кітапхана аласыз: libuniverse. (so/dylib/dll) және Әлем. (so/pyd).

Біріншісі - теңшелетін C++ кітапханасы және соңғысы Python сценарийінен импортталатын Python модулі (құжат, сынақ драйвері).

Әрине, shiboken арқылы жасалған аралық файлдар да бар (Python байланыстарын жасау үшін жасалған .h/.cpp файлдары). Ақаулықтарды жоюдың қажеті болмаса немесе қандай да бір себептермен ол компиляцияланбаған болса немесе қажетінше әрекет етпесе, олар туралы алаңдамаңыз. Содан кейін сіз Qt компаниясына қате туралы есеп бере аласыз!

Соңында біз Python бөлігіне жетеміз.

Python модулін пайдалану

Келесі шағын сценарийде біз Universe модулін қолданамыз, Icecream-тен мұра аламыз, виртуалды әдістерді енгіземіз, нысандарды жасаймыз және т.б.

from Universe import Icecream, Truck

class VanillaChocolateIcecream(Icecream):
    def __init__(self, flavor=""):
        super(VanillaChocolateIcecream, self).__init__(flavor)

    def clone(self):
        return VanillaChocolateIcecream(self.getFlavor())

    def getFlavor(self):
        return "vanilla sprinked with chocolate"

class VanillaChocolateCherryIcecream(VanillaChocolateIcecream):
    def __init__(self, flavor=""):
        super(VanillaChocolateIcecream, self).__init__(flavor)

    def clone(self):
        return VanillaChocolateCherryIcecream(self.getFlavor())

    def getFlavor(self):
        base_flavor = super(VanillaChocolateCherryIcecream, self).getFlavor()
        return base_flavor + " and a cherry"

if __name__ == '__main__':
    leave_on_destruction = True
    truck = Truck(leave_on_destruction)

    flavors = ["vanilla", "chocolate", "strawberry"]
    for f in flavors:
        icecream = Icecream(f)
        truck.addIcecreamFlavor(icecream)

    truck.addIcecreamFlavor(VanillaChocolateIcecream())
    truck.addIcecreamFlavor(VanillaChocolateCherryIcecream())

    truck.arrive()
    truck.printAvailableFlavors()
    result = truck.deliver()

    if result:
        print("All the kids got some icecream!")
    else:
        print("Aww, someone didn't get the flavor they wanted...")

    if not result:
        special_truck = Truck(truck)
        del truck

        print("")
        special_truck.setArrivalMessage("A new SPECIAL icecream truck has arrived!\n")
        special_truck.arrive()
        special_truck.addIcecreamFlavor(Icecream("SPECIAL *magical* icecream"))
        special_truck.printAvailableFlavors()
        special_truck.deliver()
        print("Now everyone got the flavor they wanted!")
        special_truck.leave()

Модульден сыныптарды импорттағаннан кейін біз дәмдерімен теңшелген екі туынды (екінші) балмұздақ түрін жасаймыз.

Содан кейін біз жүк көлігін (жүк машинасын) жасаймыз, оған балмұздақтың (балмұздақтың) бірнеше қарапайым нұсқаларын (сорттарын) және екі арнайы нұсқаларды қосамыз.

Біз балмұздақ (балмұздақ) жіберуге (жеткізуге) тырысамыз.

Егер жеткізу сәтсіз болса, біз ескі нұсқалары көшірілген жаңа жүк көлігін және барлық тұтынушыларды қанағаттандыратын жаңа сиқырлы нұсқасын жасаймыз.

Жоғарыдағы сценарий C++ түріндегі қорытындыны пайдалануды, виртуалды әдістерді қайта анықтауды, нысандарды жасауды және жоюды және т.б. қысқаша көрсетеді.

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Ол саған ұнайды ма? Әлеуметтік желілерде бөлісіңіз!

Пікірлер

Тек рұқсаты бар пайдаланушылар ғана пікір қалдыра алады.
Кіріңіз немесе Тіркеліңіз
Г

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:66ұпай,
  • Бағалау ұпайлары-1
t

C++ - Тест 001. Первая программа и типы данных

  • Нәтиже:33ұпай,
  • Бағалау ұпайлары-10
t

Qt - Тест 001. Сигналы и слоты

  • Нәтиже:52ұпай,
  • Бағалау ұпайлары-4
Соңғы пікірлер
G
GoattRockҚыр. 3, 2024, 1:50 Т.Қ.
Linux жүйесінде файлдарды қалай көшіруге болады Задумывались когда-нибудь о том, как мы привыкли доверять свои вещи службам грузоперевозок? Сейчас такие услуги стали неотъемлемой частью нашей жизни, особенно когда речь идет о переездах между …
d
dblas5Шілде 5, 2024, 11:02 Т.Ж.
QML - Сабақ 016. SQLite деректер қоры және онымен QML Qt-та жұмыс істеу Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
k
kmssrАқп. 8, 2024, 6:43 Т.Қ.
Qt Linux - Сабақ 001. Linux астында Autorun Qt қолданбасы как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
АК
Анатолий КононенкоАқп. 5, 2024, 1:50 Т.Ж.
Qt WinAPI - Сабақ 007. Qt ішінде ICMP Ping арқылы жұмыс істеу Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
Енді форумда талқылаңыз
Evgenii Legotckoi
Evgenii LegotckoiМаусым 24, 2024, 3:11 Т.Қ.
добавить qlineseries в функции Я тут. Работы оень много. Отправил его в бан.
F
FynjyШілде 22, 2024, 4:15 Т.Ж.
при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …
BlinCT
BlinCTМаусым 25, 2024, 1 Т.Ж.
Нарисовать кривую в qml Всем привет. Имеется Лист листов с тосками, точки получаны интерполяцией Лагранжа. Вопрос, как этими точками нарисовать кривую? ChartView отпадает сразу, в qt6.7 появился новый элемент…
BlinCT
BlinCTМамыр 5, 2024, 5:46 Т.Ж.
Написать свой GraphsView Всем привет. В Qt есть давольно старый обьект дял работы с графиками ChartsView и есть в 6.7 новый но очень сырой и со слабым функционалом GraphsView. По этой причине я хочу написать х…
Evgenii Legotckoi
Evgenii LegotckoiМамыр 2, 2024, 2:07 Т.Қ.
Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Добрый день. По моему мнению - да, но то, что будет касаться вызовов к функционалу Андроида, может создать огромные трудности.

Бізді әлеуметтік желілерде бақылаңыз