Sematkan / Sertakan Python.h ke dalam C ++ [Panduan Lengkap] (Python 3.9) (Windows) (Qt 5.15) [duplikat]
Ketika saya mencoba menyematkan skrip Python ke dalam program Qt C ++ saya, saya mengalami banyak masalah saat mencoba memasukkan Python.h. Fitur-fitur berikut, yang ingin saya sediakan:
- Sertakan python.h
- Jalankan String Python
- Jalankan Skrip Python
- Jalankan Skrip Python dengan Argumen
- Ini juga harus berfungsi ketika Python tidak diinstal pada mesin yang di-deploy
Oleh karena itu saya mencari di Internet untuk mencoba menemukan solusi. Dan menemukan banyak Pertanyaan dan Blog, tetapi tidak semuanya mencakup semua Masalah saya dan masih butuh waktu berjam-jam dan banyak frustrasi. Itulah mengapa saya harus menuliskan entri StackOverflow dengan solusi lengkap saya sehingga dapat membantu dan mempercepat semua pekerjaan Anda :)
Jawaban
(Jawaban ini dan semua contoh kodenya juga berfungsi dalam lingkungan non-Qt. Hanya 2. dan 4. yang khusus Qt)
- Unduh dan instal Python https://www.python.org/downloads/release
- Ubah file .pro proyek Anda dan tambahkan baris berikut (edit untuk jalur python yang benar):
INCLUDEPATH = "C:\Users\Public\AppData\Local\Programs\Python\Python39\include"
LIBS += -L"C:\Users\Public\AppData\Local\Programs\Python\Python39\libs" -l"python39"
- Contoh kode main.cpp:
#include <QCoreApplication>
#pragma push_macro("slots")
#undef slots
#include <Python.h>
#pragma pop_macro("slots")
/*!
* \brief runPy can execut a Python string
* \param string (Python code)
*/
static void runPy(const char* string){
Py_Initialize();
PyRun_SimpleString(string);
Py_Finalize();
}
/*!
* \brief runPyScript executs a Python script
* \param file (the path of the script)
*/
static void runPyScript(const char* file){
FILE* fp;
Py_Initialize();
fp = _Py_fopen(file, "r");
PyRun_SimpleFile(fp, file);
Py_Finalize();
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
runPy("from time import time,ctime\n"
"print('Today is', ctime(time()))\n");
//uncomment the following line to run a script
//runPyScript("test/decode.py");
return a.exec();
}
- Kapanpun Anda #include <Python.h> gunakan kode berikut sebagai gantinya. (Slot dari Python akan bertentangan dengan Qt Slots
#pragma push_macro("slots")
#undef slots
#include <Python.h>
#pragma pop_macro("slots")
- Setelah kompilasi, tambahkan folder python3.dll, python39.dll, serta DLL dan Lib Python ke folder kompilasi Anda. Anda dapat menemukannya di direktori root instalasi Python Anda. Ini akan memungkinkan Anda untuk menjalankan kode c ++ tertanam bahkan ketika python tidak diinstal.
Dengan langkah-langkah ini, saya bisa menjalankan python di Qt dengan kompiler MinGW dan MSVC 64 bit. Hanya MSVC dalam mode debug yang masih bermasalah.
LEBIH LANJUT:
Jika Anda ingin meneruskan argumen ke skrip python, Anda memerlukan fungsi berikut (Ini dapat dengan mudah disalin-tempel ke kode Anda):
/*!
* \brief runPyScriptArgs executs a Python script and passes arguments
* \param file (the path of the script)
* \param argc amount of arguments
* \param argv array of arguments with size of argc
*/
static void runPyScriptArgs(const char* file, int argc, char *argv[]){
FILE* fp;
wchar_t** wargv = new wchar_t*[argc];
for(int i = 0; i < argc; i++)
{
wargv[i] = Py_DecodeLocale(argv[i], nullptr);
if(wargv[i] == nullptr)
{
return;
}
}
Py_SetProgramName(wargv[0]);
Py_Initialize();
PySys_SetArgv(argc, wargv);
fp = _Py_fopen(file, "r");
PyRun_SimpleFile(fp, file);
Py_Finalize();
for(int i = 0; i < argc; i++)
{
PyMem_RawFree(wargv[i]);
wargv[i] = nullptr;
}
delete[] wargv;
wargv = nullptr;
}
Untuk menggunakan fungsi ini, panggil seperti ini (Misalnya di main Anda):
int py_argc = 2;
char* py_argv[py_argc];
py_argv[0] = "Progamm";
py_argv[1] = "Hello";
runPyScriptArgs("test/test.py", py_argc, py_argv);
Bersama dengan skrip test.py di folder uji:
import sys
if len(sys.argv) != 2:
sys.exit("Not enough args")
ca_one = str(sys.argv[0])
ca_two = str(sys.argv[1])
print ("My command line args are " + ca_one + " and " + ca_two)
Anda mendapatkan hasil berikut:
My command line args are Progamm and Hello