QList< Calamares::job_ptr > PythonQtViewStep::jobs() const { QList< Calamares::job_ptr > jobs; PythonQtObjectPtr jobsCallable = PythonQt::self()->lookupCallable( m_obj, "jobs" ); if ( jobsCallable.isNull() ) return jobs; PythonQtObjectPtr response = PythonQt::self()->callAndReturnPyObject( jobsCallable ); if ( response.isNull() ) return jobs; PythonQtObjectPtr listPopCallable = PythonQt::self()->lookupCallable( response, "pop" ); if ( listPopCallable.isNull() ) return jobs; forever { PythonQtObjectPtr aJob = PythonQt::self()->callAndReturnPyObject( listPopCallable, { 0 } ); if ( aJob.isNull() ) break; jobs.append( Calamares::job_ptr( new PythonQtJob( m_cxt, aJob ) ) ); } return jobs; }
void PythonScriptModule::Uninitialize() { // Clear script created input contexts. createdInputs_.clear(); PythonQtObjectPtr mainModule = PythonQt::self()->getMainModule(); if (!mainModule.isNull()) { mainModule.removeVariable("_pythonscriptmodule"); mainModule.removeVariable("_tundra"); } // This will remove all the signal handlers in PythonQt. // This function is only available in the modified PythonQt realXtend Tundra made. // Otherwise our app will crash when deleting the framework APIs as there are connected signals still to python slots. LogInfo("PythonScriptModule: Disconnecting all PythonQt connected signals"); PythonQt::priv()->disconnectAllSignalReceivers(); PythonQt::priv()->deleteAllSignalReceivers(); // Note that we do not call Py_Finalize() before or after PythonQt::cleanup() // as this will crash either way after doing the above. Let python release its memory when the dll is unloaded. LogInfo("PythonScriptModule: Running PythonQt cleanup"); PythonQt::cleanup(); }
void PythonScriptModule::PostInitialize() { // An error has occurred on startup. if (!pythonQtStarted_) return; // Get python main module. PythonQtObjectPtr mainModule = PythonQt::self()->getMainModule(); if (mainModule.isNull()) { LogError("PythonScriptModule::StartPythonQt(): Failed to get main module from PythonQt after init!"); return; } // Add PythonScriptModule as '_pythonscriptmodule' // and Framework as '_tundra' to python. mainModule.addObject("_pythonscriptmodule", this); mainModule.addObject("_tundra", GetFramework()); QDir pythonPlugins(Application::InstallationDirectory() + "pyplugins"); QDir pythonLibrary(pythonPlugins.absoluteFilePath("python/")); // Add Tundra python plugins source location. AddSystemPath(pythonPlugins.absolutePath()); AddSystemPath(pythonPlugins.absoluteFilePath("lib")); // Add Python Library DLL and on windows pass whole python as a archive file. /// \todo Is the 'DLLs' really needed also outside windows? AddSystemPath(pythonLibrary.absoluteFilePath("DLLs")); #ifdef _WIN32 AddSystemPath(pythonLibrary.absoluteFilePath("Python26.zip")); #endif // Connect to SceneAPI QObject::connect(GetFramework()->Scene(), SIGNAL(SceneAdded(const QString&)), this, SLOT(OnSceneAdded(const QString&))); // Console commands to ConsoleAPI GetFramework()->Console()->RegisterCommand("PyExec", "Execute given code in the embedded Python interpreter. Usage: PyExec(mycodestring)", this, SLOT(ConsoleRunString(const QStringList&))); GetFramework()->Console()->RegisterCommand("PyLoad", "Execute a python file. Usage: PyLoad(mypymodule)", this, SLOT(ConsoleRunFile(const QStringList&))); GetFramework()->Console()->RegisterCommand("PyRestart", "Restarts the Tundra Python ModuleManager", this, SLOT(ConsoleRestartPython(const QStringList&))); GetFramework()->Console()->RegisterCommand("PyConsole", "Creates a new Python console window.", this, SLOT(ShowConsole())); // Done in PostInitialize() so all modules/APIs are loaded and initialized. //StartPythonModuleManager(); // --p --python --pythonapitests are special command line options that on purpose not put // to the Framework program options parsing. So lets do a special parse here for there hidden variables. /// \todo See if we should return --p --python as official cmd line options back to Framework. Probably best to have modules give own params somehow, /// we should not mess python specific things to core SDK params in Framework.cpp :I namespace po = boost::program_options; po::variables_map commandLineVariables; po::options_description commandLineDescriptions; commandLineDescriptions.add_options() ("p", po::value<std::string>(), "Run a python script on startup") ("python", po::value<std::string>(), "Run a python script on startup") ("pythonapitests", "Run a python api test script on startup"); try { /// \note QApplication::argc() and QApplication::argv() are deprecated. po::store(po::command_line_parser(QApplication::argc(), QApplication::argv()).options(commandLineDescriptions).allow_unregistered().run(), commandLineVariables); } catch(std::exception &e) { LogWarning(Name() + ": " + + e.what()); } po::notify(commandLineVariables); if (commandLineVariables.count("python")) RunScript(commandLineVariables["python"].as<std::string>().c_str()); if (commandLineVariables.count("p")) RunScript(commandLineVariables["p"].as<std::string>().c_str()); LoadStartupScripts(); }