У меня есть проект 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()
Задача ещё не решена.
Других решений пока нет …