Merge pull request #10619 from wwmayer/fix_issue_10617

Gui: fixes #10617: Ctrl+C only stop python running in console not from macros
This commit is contained in:
Yorik van Havre
2023-09-11 17:36:43 +02:00
committed by GitHub
6 changed files with 89 additions and 1 deletions

View File

@@ -44,6 +44,7 @@
#include "Macro.h"
#include "MainWindow.h"
#include "PythonEditor.h"
#include "WaitCursor.h"
using namespace Gui;
@@ -80,6 +81,7 @@ DlgMacroExecuteImp::DlgMacroExecuteImp( QWidget* parent, Qt::WindowFlags fl )
, WindowParameter( "Macro" )
, ui(new Ui_DlgMacroExecute)
{
watcher = std::make_unique<PythonTracingWatcher>(this);
ui->setupUi(this);
setupConnections();
@@ -300,6 +302,9 @@ void DlgMacroExecuteImp::accept()
QFileInfo fi(dir, item->text(0));
try {
WaitCursor wc;
PythonTracingLocker tracelock(watcher->getTrace());
getMainWindow()->appendRecentMacro(fi.filePath());
Application::Instance->macroManager()->run(Gui::MacroManager::File, fi.filePath().toUtf8());
// after macro run recalculate the document

View File

@@ -26,6 +26,7 @@
#include <QDialog>
#include <memory>
#include "PythonTracing.h"
#include "Window.h"
class QTreeWidgetItem;
@@ -71,6 +72,7 @@ protected:
QString macroPath;
private:
std::unique_ptr<PythonTracingWatcher> watcher;
std::unique_ptr<Ui_DlgMacroExecute> ui;
};

View File

@@ -50,6 +50,8 @@
#include "Macro.h"
#include "MainWindow.h"
#include "PythonEditor.h"
#include "PythonTracing.h"
#include "WaitCursor.h"
#include <Base/Exception.h>
#include <Base/Interpreter.h>
@@ -596,9 +598,13 @@ PythonEditorView::PythonEditorView(PythonEditor* editor, QWidget* parent)
{
connect(this, &PythonEditorView::changeFileName,
editor, &PythonEditor::setFileName);
watcher = new PythonTracingWatcher(this);
}
PythonEditorView::~PythonEditorView() = default;
PythonEditorView::~PythonEditorView()
{
delete watcher;
}
/**
* Runs the action specified by \a pMsg.
@@ -644,6 +650,8 @@ void PythonEditorView::executeScript()
if (EditorView::onHasMsg("Save"))
EditorView::onMsg("Save", nullptr);
try {
WaitCursor wc;
PythonTracingLocker tracelock(watcher->getTrace());
Application::Instance->macroManager()->run(Gui::MacroManager::File,fileName().toUtf8());
}
catch (const Base::SystemExitException&) {

View File

@@ -41,6 +41,7 @@ namespace Gui {
class EditorViewP;
class TextEdit;
class PythonTracingWatcher;
/**
* A special view class which sends the messages from the application to
@@ -140,6 +141,7 @@ public Q_SLOTS:
private:
PythonEditor* _pye;
PythonTracingWatcher* watcher;
};
class SearchBar : public QWidget

View File

@@ -23,12 +23,15 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <QApplication>
#include <QKeyEvent>
#include <QTime>
#include <QGuiApplication>
#endif
#include "PythonTracing.h"
#include <App/Application.h>
#include <Base/Interpreter.h>
using namespace Gui;
@@ -113,6 +116,7 @@ void PythonTracing::setPythonTraceEnabled(bool enabled) const
Private::profilerDisabled = true;
}
Base::PyGILStateLocker lock;
PyEval_SetTrace(trace, nullptr);
}
@@ -159,3 +163,36 @@ PythonTracingLocker::~PythonTracingLocker()
{
trace.deactivate();
}
// ------------------------------------------------------------------------------------------------
PythonTracingWatcher::PythonTracingWatcher(QObject* parent)
: QObject(parent)
{
qApp->installEventFilter(this);
}
PythonTracingWatcher::~PythonTracingWatcher()
{
qApp->removeEventFilter(this);
}
bool PythonTracingWatcher::eventFilter(QObject* object, QEvent* event)
{
if (event && event->type() == QEvent::ShortcutOverride) {
auto kevent = static_cast<QKeyEvent*>(event);
if (kevent->key() == Qt::Key_C && kevent->modifiers() == Qt::ControlModifier) {
if (trace.interrupt()) {
return true;
}
}
}
return QObject::eventFilter(object, event);
}
PythonTracing& PythonTracingWatcher::getTrace()
{
trace.fetchFromSettings();
return trace;
}

View File

@@ -24,6 +24,7 @@
#ifndef GUI_PYTHONTRACING_H
#define GUI_PYTHONTRACING_H
#include <QObject>
#include <Python.h>
#include <frameobject.h>
#include <memory>
@@ -113,6 +114,39 @@ private:
PythonTracing& trace;
};
class GuiExport PythonTracingWatcher : public QObject
{
// NOLINTNEXTLINE
Q_OBJECT
public:
PythonTracingWatcher(QObject* parent = nullptr);
~PythonTracingWatcher() override;
/*!
* \brief eventFilter
* Checks for Ctrl+C keyboard events and if pressed interrupts the Python interpreter.
* \param object
* \param event
* \return
*/
bool eventFilter(QObject* object, QEvent* event) override;
/*!
* \brief getTrace
* Returns the Python tracing object. It's up to the calling instance to activate and decativate it.
* \return PythonTracing
*/
PythonTracing& getTrace();
PythonTracingWatcher(const PythonTracingWatcher&) = delete;
PythonTracingWatcher(PythonTracingWatcher&&) = delete;
PythonTracingWatcher& operator = (const PythonTracingWatcher&) = delete;
PythonTracingWatcher& operator = (PythonTracingWatcher&&) = delete;
private:
PythonTracing trace;
};
} // namespace Gui
#endif // GUI_PYTHONTRACING_H