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;
}
Beispiel #2
0
    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();
    }
Beispiel #3
0
    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();
    }