Python Tkinter встроен в поток C ++ - PullRequest
0 голосов
/ 25 декабря 2018

У меня есть проект на C ++, в который я хотел бы добавить встроенный интерпретатор python.Я действительно преуспел в этом с помощью простых сценариев, но когда я пытаюсь что-то сделать с Tkinter, он открывает пустое окно и никогда не рисует ни фрейм, ни содержимое.Я почти уверен, что это связано с GIL, но не удалось найти какую-то комбинацию вызовов, которые работают.Я сделал простой пример, который иллюстрирует это с помощью файла C ++ и скрипта Python, который запускает скомпилированная программа.Если вы раскомментируете строку MyPythonThread и закомментируете две, которые запускают ее в потоке, то она работает как положено.

Кажется, что python знает, находится ли он в «основном» потоке или нет, независимо от того, какой потокЯ Py_Initialize от.

Другая информация: я тестирую это на Mac OS X 10.13.6 с установленным доморощенным python 2.7.15.

//
// Compile with: g++ `python-config --cflags --libs` --std=c++11 test.cc
//

#include <cstdio>
#include <Python.h>
#include <thread>

void MyPythonThread(void)
{
    PyEval_InitThreads();
    Py_Initialize();

    const char *fname = "test.py";
    PySys_SetArgv( 1, (char**)&fname );
    auto fil = std::fopen(fname, "r");
    PyRun_AnyFileEx( fil, NULL, 1 );

}

int main(int narg, char * argv[])
{

    // This works
//  MyPythonThread();

    // This does not
    std::thread thr(MyPythonThread);
    thr.join();

    return 0;
}

Вот скрипт Python, который онработает:

#!/usr/bin/env python

import Tkinter as tk

window = tk.Tk()
top_frame = tk.Frame(window).pack()
b1 = tk.Button(top_frame, text = "Button").pack()

window.mainloop()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...