From: BERNHARD Martin OpenCascade Date: Mon, 30 Oct 2023 14:13:22 +0000 (+0100) Subject: Merge commit '4bda6c883bff2af152b1de8d7f6d4820780c2cd2' X-Git-Tag: V9_12_0b1^0 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=cc14dfe0c087d1459c8b593ad7d262ddec495603;hp=4bda6c883bff2af152b1de8d7f6d4820780c2cd2;p=modules%2Fgui.git Merge commit '4bda6c883bff2af152b1de8d7f6d4820780c2cd2' --- diff --git a/doc/salome/gui/input/introduction_to_gui.rst b/doc/salome/gui/input/introduction_to_gui.rst index edd30b0ba..026866837 100644 --- a/doc/salome/gui/input/introduction_to_gui.rst +++ b/doc/salome/gui/input/introduction_to_gui.rst @@ -62,8 +62,7 @@ input fields. using_notebook.rst themes.rst using_catalog_generator.rst - working_with_python_scripts.rst - working_with_python_console.rst + working_with_python_scripts.rst using_registry_tool.rst viewers_chapter.rst setting_preferences.rst diff --git a/doc/salome/gui/input/working_with_python_console.rst b/doc/salome/gui/input/working_with_python_console.rst deleted file mode 100644 index e0d84ffbb..000000000 --- a/doc/salome/gui/input/working_with_python_console.rst +++ /dev/null @@ -1,93 +0,0 @@ -.. _python_console_page: - -****************** -Python Console -****************** - -**Python console** - Window for Python interpreter. This window functions like a standard document: -the pop-up menu invoked by right-click in this window gives access to **Copy/Paste/SelectAll/ClearAll** options. - -You can run a Python script in interactive mode by typing expressions line by line or by loading a Python file -from the main menu **File -> Load Script**. - -================== -Asynchronous mode -================== - -By default the console is always initialized in asynchronous mode when the Python commands are executed in the separated thread -that does not block the main GUI loop. So, you'll see any intermediate output from the running script even if the script didn't finish yet. - -In the synchronous mode each Python command is executed in the main GUI thread, then GUI is blocked until the command is finished. -It could be an issue if you run a time consuming Python script, because you won't see any output till the end of execution. - -If you need to run a script in synchronous mode for whatever reason, set ``PYTHON_CONSOLE_SYNC`` environment variable before Salome start: - -.. code-block:: console - - export PYTHON_CONSOLE_SYNC=1 - -================== -Tracing -================== - -To output in console currently executed functions, we're adding tracing code to the start and at the end -of the command to deactivate it immediately after execution. - -This mechanism is turned off by default. Set ``PYCONSOLE_TRACE`` before SALOME start to activate it: - -.. code-block:: console - - export PYCONSOLE_TRACE=1 - -If the tracing is on while the script is running we can see functions enter and return calls -with ``>>`` and ``<<`` marks followed by line number and function name. Tracing function prints only calls to functions -defined in the current script to prevent printing of thousands of lines for builtin functions in some cases. - -Example of a script with defined functions: - -.. code-block:: python - :linenos: - - #!/usr/bin/env python - - import time - - def sum(x, y): - time.sleep(3) - return x + y - - def sub(x, y): - time.sleep(3) - return x - y - - def prod(x, y): - time.sleep(3) - return x * y - - def div(x, y): - time.sleep(3) - return x / y - - x = 5 - y = 2 - - sum(x, y) - sub(x, y) - prod(x, y) - div(x, y) - -And output in the Python console: - -.. code-block:: console - - >>> sys.setprofile(lambda frame, event, arg: print('>>', frame.f_lineno, ': ', frame.f_code.co_name) if event == 'call' and frame.f_code.co_filename == '/home/function_calls.py' and frame.f_code.co_name != '' else print('<<', frame.f_lineno, ': ', frame.f_code.co_name) if event == 'return' and frame.f_code.co_filename == '/home/function_calls.py' and frame.f_code.co_name != '' else None); exec(compile(open('/home/function_calls.py', 'rb').read(), '/home/function_calls.py', 'exec')); sys.setprofile(None); - >> 5 : sum - << 7 : sum - >> 9 : sub - << 11 : sub - >> 13 : prod - << 15 : prod - >> 17 : div - << 19 : div - >>> - diff --git a/src/SUIT/SUIT_Tools.cxx b/src/SUIT/SUIT_Tools.cxx index c5802ffbd..03389703e 100644 --- a/src/SUIT/SUIT_Tools.cxx +++ b/src/SUIT/SUIT_Tools.cxx @@ -26,7 +26,6 @@ #include #include -#include /*! Traces output to log-file. @@ -78,47 +77,3 @@ void SUIT_Tools::centerWidget( QWidget* src, const QWidget* ref ) { SUIT_Tools::alignWidget( src, ref, Qt::AlignCenter ); } - -/*! - Add tracing code to given python command if it was activated by PYCONSOLE_TRACE env variable. - Immediately return if PYCONSOLE_TRACE wasn't set. -*/ -void SUIT_Tools::addTraceToPythonCommand(const QString& fileName, QString& command) -{ - auto isPythonTraceEnabled = []() -> bool - { - const char* envVar = std::getenv("PYCONSOLE_TRACE"); - - if (envVar && (envVar[0] != '\0')) - { - try - { - const long long numValue = std::stoll(envVar); - return numValue > 0; - } - catch(const std::exception& e) - { - std::cerr << e.what() << '\n'; - } - } - - return false; - }; - - static const bool isActivated = isPythonTraceEnabled(); - if (!isActivated) - { - return; - } - - // Using sys.setprofile() instead of sys.settrace() because we don't need any other events except of 'call' and 'return'. - // Another reason: the trace function for sys.settrace() must return itself, so we can't use it properly with lambda. - command = QString("sys.setprofile(lambda frame, event, arg: " - "print('>>', frame.f_lineno, ': ', frame.f_code.co_name) if event == 'call' and frame.f_code.co_filename == '%1' and frame.f_code.co_name != '' else " - "print('<<', frame.f_lineno, ': ', frame.f_code.co_name) if event == 'return' and frame.f_code.co_filename == '%1' and frame.f_code.co_name != '' else " - "None); " - "%2; " - "sys.setprofile(None); "). - arg(fileName). - arg(command); -} diff --git a/src/SUIT/SUIT_Tools.h b/src/SUIT/SUIT_Tools.h index 13b3ed9d3..cc57dffd8 100644 --- a/src/SUIT/SUIT_Tools.h +++ b/src/SUIT/SUIT_Tools.h @@ -44,8 +44,6 @@ public: static QString fontToString( const QFont& font ); static void centerWidget( QWidget* src, const QWidget* ref ); - - static void addTraceToPythonCommand(const QString& fileName, QString& command); }; #endif diff --git a/src/SalomeApp/SalomeApp_Application.cxx b/src/SalomeApp/SalomeApp_Application.cxx index a7046eaca..804a98dbd 100644 --- a/src/SalomeApp/SalomeApp_Application.cxx +++ b/src/SalomeApp/SalomeApp_Application.cxx @@ -534,7 +534,28 @@ void SalomeApp_Application::onUnloadDoc( bool ask ) /*!SLOT. Create new study and load script*/ void SalomeApp_Application::onNewWithScript() { - execScript(true); + QStringList filtersList; + filtersList.append(tr("PYTHON_FILES_FILTER")); + filtersList.append(tr("ALL_FILES_FILTER")); + + QString anInitialPath = ""; + if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() ) + anInitialPath = QDir::currentPath(); + + QString aFile = SUIT_FileDlg::getFileName( desktop(), anInitialPath, filtersList, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), true, true ); + + if ( !aFile.isEmpty() ) + { + onNewDoc(); + +#ifndef DISABLE_PYCONSOLE + QString command = QString("exec(open(\"%1\", \"rb\").read())").arg(aFile); + PyConsole_Console* pyConsole = pythonConsole(); + PropertyMgr propm( this, "IsLoadedScript", true ); + if ( pyConsole ) + pyConsole->exec( command ); +#endif + } } @@ -989,7 +1010,26 @@ void SalomeApp_Application::onLoadScript( ) return; } - execScript(false); + QStringList filtersList; + filtersList.append(tr("PYTHON_FILES_FILTER")); + filtersList.append(tr("ALL_FILES_FILTER")); + + QString anInitialPath = ""; + if ( SUIT_FileDlg::getLastVisitedPath().isEmpty() ) + anInitialPath = QDir::currentPath(); + + QString aFile = SUIT_FileDlg::getFileName( desktop(), anInitialPath, filtersList, tr( "TOT_DESK_FILE_LOAD_SCRIPT" ), true, true ); + + if ( !aFile.isEmpty() ) + { +#ifndef DISABLE_PYCONSOLE + QString command = QString("exec(compile(open('%1', 'rb').read(), '%1', 'exec'))").arg(aFile); + PyConsole_Console* pyConsole = pythonConsole(); + PropertyMgr propm( this, "IsLoadedScript", true ); + if ( pyConsole ) + pyConsole->exec(command); +#endif + } } /*!Private SLOT. On save GUI state.*/ @@ -2102,50 +2142,6 @@ PyConsole_Interp* SalomeApp_Application::createPyInterp() #endif // DISABLE_PYCONSOLE -/* - Opens a file dialog to choose a python script. -*/ -QString SalomeApp_Application::getScriptFileName() -{ - QStringList filtersList; - filtersList.append(tr("PYTHON_FILES_FILTER")); - filtersList.append(tr("ALL_FILES_FILTER")); - - const QString anInitialPath = - SUIT_FileDlg::getLastVisitedPath().isEmpty() ? QDir::currentPath() : ""; - - return SUIT_FileDlg::getFileName(desktop(), anInitialPath, filtersList, tr("TOT_DESK_FILE_LOAD_SCRIPT"), true, true); -} - -/* - Execute script in python console. -*/ -void SalomeApp_Application::execScript(bool isNewDoc) -{ - const QString aFile = getScriptFileName(); - if (aFile.isEmpty()) - { - return; - } - - if (isNewDoc) - { - onNewDoc(); - } - -#ifndef DISABLE_PYCONSOLE - PyConsole_Console* pyConsole = pythonConsole(); - PropertyMgr propm(this, "IsLoadedScript", true); - if (pyConsole) - { - QString command = QString("exec(compile(open('%1', 'rb').read(), '%1', 'exec'))").arg(aFile); - SUIT_Tools::addTraceToPythonCommand(aFile, command); - - pyConsole->exec(command); - } -#endif -} - void SalomeApp_Application::ensureShaperIsActivated() { SalomeApp_Study* study = dynamic_cast(activeStudy()); diff --git a/src/SalomeApp/SalomeApp_Application.h b/src/SalomeApp/SalomeApp_Application.h index e58dd883b..f94e11b9c 100644 --- a/src/SalomeApp/SalomeApp_Application.h +++ b/src/SalomeApp/SalomeApp_Application.h @@ -199,9 +199,6 @@ private: void createExtraActions(); void ensureShaperIsActivated(); - QString getScriptFileName(); - void execScript(bool isNewDoc); - private: #ifndef DISABLE_PYCONSOLE QPointer myNoteBook; // Notebook instance diff --git a/tools/PyConsole/src/PyConsole_Editor.cxx b/tools/PyConsole/src/PyConsole_Editor.cxx index e0e7f4a1a..3c597e7b6 100644 --- a/tools/PyConsole/src/PyConsole_Editor.cxx +++ b/tools/PyConsole/src/PyConsole_Editor.cxx @@ -183,7 +183,7 @@ void PyConsole_Editor::init() myCmdInHistory = -1; myEventLoop = 0; myShowBanner = true; - myIsSync = false; + myIsSync = true; myIsSuppressOutput = false; myMultiLinePaste = false; myAutoCompletion = false;