Improve sys.stdin redirection mechanism
This commit is contained in:
parent
e3cbca1062
commit
fa12664f87
|
@ -392,7 +392,7 @@ PythonConsole::PythonConsole(QWidget *parent)
|
||||||
"Type 'help', 'copyright', 'credits' or 'license' for more information.")
|
"Type 'help', 'copyright', 'credits' or 'license' for more information.")
|
||||||
.arg(QString::fromAscii(version)).arg(QString::fromAscii(platform));
|
.arg(QString::fromAscii(version)).arg(QString::fromAscii(platform));
|
||||||
d->output = d->info;
|
d->output = d->info;
|
||||||
printPrompt(false);
|
printPrompt(PythonConsole::Complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Destroys the object and frees any allocated resources */
|
/** Destroys the object and frees any allocated resources */
|
||||||
|
@ -504,7 +504,9 @@ void PythonConsole::keyPressEvent(QKeyEvent * e)
|
||||||
d->history.append( QLatin1String("# ") + inputLine ); //< put line to history ...
|
d->history.append( QLatin1String("# ") + inputLine ); //< put line to history ...
|
||||||
inputLineBegin.insertText( QString::fromAscii("# ") ); //< but comment it on console
|
inputLineBegin.insertText( QString::fromAscii("# ") ); //< but comment it on console
|
||||||
setTextCursor( inputLineBegin );
|
setTextCursor( inputLineBegin );
|
||||||
printPrompt( d->interpreter->hasPendingInput() ); //< print adequate prompt
|
printPrompt(d->interpreter->hasPendingInput() //< print adequate prompt
|
||||||
|
? PythonConsole::Incomplete
|
||||||
|
: PythonConsole::Complete);
|
||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
|
@ -600,10 +602,15 @@ void PythonConsole::insertPythonError ( const QString& err )
|
||||||
d->error += err;
|
d->error += err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PythonConsole::onFlush()
|
||||||
|
{
|
||||||
|
printPrompt(PythonConsole::Flush);
|
||||||
|
}
|
||||||
|
|
||||||
/** Prints the ps1 prompt (>>> ) for complete and ps2 prompt (... ) for
|
/** Prints the ps1 prompt (>>> ) for complete and ps2 prompt (... ) for
|
||||||
* incomplete commands to the console window.
|
* incomplete commands to the console window.
|
||||||
*/
|
*/
|
||||||
void PythonConsole::printPrompt(bool incomplete)
|
void PythonConsole::printPrompt(PythonConsole::Prompt mode)
|
||||||
{
|
{
|
||||||
// write normal messages
|
// write normal messages
|
||||||
if (!d->output.isEmpty()) {
|
if (!d->output.isEmpty()) {
|
||||||
|
@ -632,8 +639,15 @@ void PythonConsole::printPrompt(bool incomplete)
|
||||||
else
|
else
|
||||||
block.setUserState(0);
|
block.setUserState(0);
|
||||||
|
|
||||||
incomplete ? cursor.insertText(QString::fromAscii("... "))
|
switch (mode)
|
||||||
: cursor.insertText(QString::fromAscii(">>> "));
|
{
|
||||||
|
case PythonConsole::Incomplete:
|
||||||
|
cursor.insertText(QString::fromAscii("... "));
|
||||||
|
case PythonConsole::Complete:
|
||||||
|
cursor.insertText(QString::fromAscii(">>> "));
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
cursor.endEditBlock();
|
cursor.endEditBlock();
|
||||||
|
|
||||||
// move cursor to the end
|
// move cursor to the end
|
||||||
|
@ -706,9 +720,10 @@ void PythonConsole::runSource(const QString& line)
|
||||||
QMessageBox::critical(this, tr("Python console"), tr("Unhandled unknown C++ exception."));
|
QMessageBox::critical(this, tr("Python console"), tr("Unhandled unknown C++ exception."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printPrompt(incomplete ? PythonConsole::Incomplete
|
||||||
|
: PythonConsole::Complete);
|
||||||
PySys_SetObject("stdout", default_stdout);
|
PySys_SetObject("stdout", default_stdout);
|
||||||
PySys_SetObject("stderr", default_stderr);
|
PySys_SetObject("stderr", default_stderr);
|
||||||
printPrompt(incomplete);
|
|
||||||
d->interactive = false;
|
d->interactive = false;
|
||||||
for (QStringList::Iterator it = d->statements.begin(); it != d->statements.end(); ++it)
|
for (QStringList::Iterator it = d->statements.begin(); it != d->statements.end(); ++it)
|
||||||
printStatement(*it);
|
printStatement(*it);
|
||||||
|
@ -751,7 +766,7 @@ void PythonConsole::printStatement( const QString& cmd )
|
||||||
cursor.movePosition(QTextCursor::End);
|
cursor.movePosition(QTextCursor::End);
|
||||||
cursor.insertText( *it );
|
cursor.insertText( *it );
|
||||||
d->history.append( *it );
|
d->history.append( *it );
|
||||||
printPrompt(false);
|
printPrompt(PythonConsole::Complete);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -984,7 +999,7 @@ void PythonConsole::runSourceFromMimeData(const QString& source)
|
||||||
buffer.append(line);
|
buffer.append(line);
|
||||||
int ret = d->interpreter->compileCommand(buffer.join(QLatin1String("\n")).toUtf8());
|
int ret = d->interpreter->compileCommand(buffer.join(QLatin1String("\n")).toUtf8());
|
||||||
if (ret == 1) { // incomplete
|
if (ret == 1) { // incomplete
|
||||||
printPrompt(true);
|
printPrompt(PythonConsole::Incomplete);
|
||||||
}
|
}
|
||||||
else if (ret == 0) { // complete
|
else if (ret == 0) { // complete
|
||||||
// check if the following lines belong to the previous block
|
// check if the following lines belong to the previous block
|
||||||
|
@ -1001,7 +1016,7 @@ void PythonConsole::runSourceFromMimeData(const QString& source)
|
||||||
// is finished
|
// is finished
|
||||||
if (ret == -1) {
|
if (ret == -1) {
|
||||||
// the command is not finished yet
|
// the command is not finished yet
|
||||||
printPrompt(true);
|
printPrompt(PythonConsole::Incomplete);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
runSource(buffer.join(QLatin1String("\n")));
|
runSource(buffer.join(QLatin1String("\n")));
|
||||||
|
@ -1094,7 +1109,7 @@ void PythonConsole::onClearConsole()
|
||||||
{
|
{
|
||||||
clear();
|
clear();
|
||||||
d->output = d->info;
|
d->output = d->info;
|
||||||
printPrompt(false);
|
printPrompt(PythonConsole::Complete);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PythonConsole::onSaveHistoryAs()
|
void PythonConsole::onSaveHistoryAs()
|
||||||
|
@ -1312,6 +1327,7 @@ PythonInputField::PythonInputField(QWidget* parent)
|
||||||
|
|
||||||
editField = new PythonEditor(this);
|
editField = new PythonEditor(this);
|
||||||
gridLayout->addWidget(editField, 0, 0, 1, 1);
|
gridLayout->addWidget(editField, 0, 0, 1, 1);
|
||||||
|
setFocusProxy(editField);
|
||||||
|
|
||||||
QHBoxLayout* hboxLayout = new QHBoxLayout();
|
QHBoxLayout* hboxLayout = new QHBoxLayout();
|
||||||
hboxLayout->setSpacing(6);
|
hboxLayout->setSpacing(6);
|
||||||
|
|
|
@ -96,6 +96,12 @@ class GuiExport PythonConsole : public TextEdit, public WindowParameter
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
enum Prompt {
|
||||||
|
Complete = 0,
|
||||||
|
Incomplete = 1,
|
||||||
|
Flush = 2
|
||||||
|
};
|
||||||
|
|
||||||
PythonConsole(QWidget *parent = 0);
|
PythonConsole(QWidget *parent = 0);
|
||||||
~PythonConsole();
|
~PythonConsole();
|
||||||
|
|
||||||
|
@ -108,6 +114,7 @@ public Q_SLOTS:
|
||||||
void onCopyHistory();
|
void onCopyHistory();
|
||||||
void onCopyCommand();
|
void onCopyCommand();
|
||||||
void onClearConsole();
|
void onClearConsole();
|
||||||
|
void onFlush();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void visibilityChanged (bool visible);
|
void visibilityChanged (bool visible);
|
||||||
|
@ -131,7 +138,7 @@ protected:
|
||||||
private:
|
private:
|
||||||
void runSource(const QString&);
|
void runSource(const QString&);
|
||||||
bool isComment(const QString&) const;
|
bool isComment(const QString&) const;
|
||||||
void printPrompt(bool);
|
void printPrompt(Prompt);
|
||||||
void insertPythonOutput(const QString&);
|
void insertPythonOutput(const QString&);
|
||||||
void insertPythonError (const QString&);
|
void insertPythonError (const QString&);
|
||||||
void runSourceFromMimeData(const QString&);
|
void runSourceFromMimeData(const QString&);
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
# include <QByteArray>
|
# include <QByteArray>
|
||||||
# include <QInputDialog>
|
# include <QInputDialog>
|
||||||
# include <QEventLoop>
|
# include <QEventLoop>
|
||||||
|
# include <QTimer>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "PythonConsolePy.h"
|
#include "PythonConsolePy.h"
|
||||||
|
@ -292,12 +293,18 @@ PythonStdin::PythonStdin(PythonConsole *pc)
|
||||||
: pyConsole(pc)
|
: pyConsole(pc)
|
||||||
{
|
{
|
||||||
editField = new PythonInputField(/*getMainWindow()*/);
|
editField = new PythonInputField(/*getMainWindow()*/);
|
||||||
|
timer = new QTimer();
|
||||||
|
timer->setInterval(250);
|
||||||
|
QObject::connect(timer, SIGNAL(timeout()),
|
||||||
|
editField, SLOT(hide()));
|
||||||
|
console = getMainWindow()->findChild<PythonConsole*>();
|
||||||
}
|
}
|
||||||
|
|
||||||
PythonStdin::~PythonStdin()
|
PythonStdin::~PythonStdin()
|
||||||
{
|
{
|
||||||
// call deleteLater() because deleting immediately causes problems
|
// call deleteLater() because deleting immediately causes problems
|
||||||
editField->deleteLater();
|
editField->deleteLater();
|
||||||
|
timer->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
Py::Object PythonStdin::repr()
|
Py::Object PythonStdin::repr()
|
||||||
|
@ -310,14 +317,16 @@ Py::Object PythonStdin::repr()
|
||||||
|
|
||||||
Py::Object PythonStdin::readline(const Py::Tuple& args)
|
Py::Object PythonStdin::readline(const Py::Tuple& args)
|
||||||
{
|
{
|
||||||
|
if (console)
|
||||||
|
console->onFlush();
|
||||||
|
timer->stop();
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
QObject::connect(editField, SIGNAL(textEntered()), &loop, SLOT(quit()));
|
QObject::connect(editField, SIGNAL(textEntered()), &loop, SLOT(quit()));
|
||||||
editField->clear();
|
editField->clear();
|
||||||
editField->show();
|
editField->show();
|
||||||
|
editField->setFocus();
|
||||||
loop.exec();
|
loop.exec();
|
||||||
QString txt = editField->getText();
|
QString txt = editField->getText();
|
||||||
if (txt.isEmpty())
|
timer->start();
|
||||||
editField->hide();
|
|
||||||
|
|
||||||
return Py::String((const char*)txt.toAscii());
|
return Py::String((const char*)txt.toAscii());
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,8 @@
|
||||||
|
|
||||||
#include <CXX/Extensions.hxx>
|
#include <CXX/Extensions.hxx>
|
||||||
|
|
||||||
|
class QTimer;
|
||||||
|
|
||||||
namespace Gui {
|
namespace Gui {
|
||||||
class PythonConsole;
|
class PythonConsole;
|
||||||
class PythonInputField;
|
class PythonInputField;
|
||||||
|
@ -140,6 +142,8 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PythonInputField* editField;
|
PythonInputField* editField;
|
||||||
|
PythonConsole* console;
|
||||||
|
QTimer* timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Gui
|
} // namespace Gui
|
||||||
|
|
Loading…
Reference in New Issue
Block a user