Is there any way to connect the Python scripts to the Button click event?



  • I am facing an issue and hope someone can help me on this.

    I have a python script for performing some operations and I want to execute this script on the button click event from my application GUI.

    Is there any way to connect the python scripts to the Qt GUI application.
    Please let me know if there is any document or example related to it.

    Thanks.



  • You can use QProcess() and execute Python interpreter.



  • Thanks Denis... I will try this
    I have another question here...
    Is it possible to display the data of python command window on QTextEdit box or any other Qt widget?



  • Sure. QProcess is a QIODevice subclass, and it suppies signals that tell you if data arrives (the output of your Python script) that you can then read and use however you like, including setting it as the text of a QTextEdit widget.



  • Hi,

    I tried executing my python script using QProcess but didn't get any output

    @QProcess *myProcess = new QProcess();
    QString program = "C:\Test.py";
    int i = myProcess->execute(program);@

    I am always getting the value of i as -2 (process cannot be started)

    Please let me know if I am missing something here.

    Thank You



  • You need to connect myProcess to the signal readyReadStandardOutput, then you will be able to receive data.

    The signal finished tells you if the program has finished and how.

    Check the "reference":http://doc.qt.nokia.com/latest/qprocess.html for more information!



  • Are you sure that you can actually start a python script that way? AFAIK, you start the using something like
    @python.exe "C:\Test.py"
    @
    A python script is not an executable by itself, after all.



  • I tried running the application using the below code but still I am getting the same result

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi( this );

    myProcess = new QProcess();
    
    connect( myProcess,
             SIGNAL( readyReadStandardOutput() ),
             this, SLOT( m_outputData() ) );
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::on_pushButton_clicked()
    {
    QString program = ""D:/Test.py"";
    program.prepend("python.exe ");

    int i = myProcess->execute( program );
    
    std::cout<<i<<"\n";
    

    }

    void MainWindow::m_outputData()
    {
    QByteArray newData = myProcess->readAllStandardOutput();
    std::cout<<newData.data()<<"\n";
    }
    @

    I am always getting the value of i as -2, but if i run the same program on QT2010.04 I am getting the value of i as 0 but no output and no error.

    I tried to debug and I found that my control never goes to m_output() function.

    Please let me know if I am missing something here.

    Thank You



  • Better put the arguments in a QStringList. Also, the args should not be put into quotation marks itself.

    QProcess::execute() is a static method, you should not call it on an instance.

    As you call the static method, your signal/slot connection will never be used.

    For the static version use:

    @
    QString exe = "python.exe";
    QStringList args;
    args << "D:/Test.py";

    int result = QProcess::execute(exe, args);
    @

    For the non-static version, see the docs in [[Doc:QProcess]].



  • I tried the following code, but getting the same result

    @#include "mainwindow.h"
    #include "ui_mainwindow.h"

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    myProcess = new QProcess();
    
    connect(myProcess,SIGNAL(readyReadStandardOutput()),this,SLOT(out()));
    

    }

    MainWindow::~MainWindow()
    {
    delete ui;
    }

    void MainWindow::changeEvent(QEvent *e)
    {
    QMainWindow::changeEvent(e);
    switch (e->type()) {
    case QEvent::LanguageChange:
    ui->retranslateUi(this);
    break;
    default:
    break;
    }
    }

    void MainWindow::on_pushButton_clicked()
    {
    QString exe = "python.exe";
    QStringList args;
    args << "C:/Test.py";

    myProcess->start(exe, args);

    //int result = QProcess::execute(exe);
    //std::cout<<result<<"\n";
    }

    void MainWindow::out()
    {
    std::cout<<"Hello\n";
    QByteArray newData = myProcess->readAllStandardOutput();

    std::cout<<newData.data();
    }
    @

    If I try
    @QString exe = "notepad.exe";
    myProcess->statr(exe);@

    it works fine and notepad window gets open, but I am not able to start the Python.exe

    Please let me know if anybody can help me on this.

    Thank You



  • I am not sure that Qt does path translation for arguments of QProcess (I guess not). Perhaps it would work to use

    @
    QString exe = "python.exe";
    QStringList args;
    args << "C:\Test.py";

    myProcess->start(exe, args);
    @

    instead?

    Edit:
    Also, check if the python executable is really in your path, and is actually called "python.exe".



  • Thanks Andre.

    I have added Python executable path in my environment variable.

    @ QString exe = "Python";
    QStringList args;
    args << "C:/Test.py";

    myProcess->start(exe,args);@

    Using the above code I am able to start the process as when i click again on button I am getting a message QProcess::start: Process is already running.
    But I am not able to see the Python command window

    And the following code is never get hit

    @void MainWindow::out()
    {
    std::cout<<"Hello\n";
    ui->lineEdit->setText("In Out Function");
    QByteArray newData = myProcess->readAllStandardOutput();

    std::cout<<newData.data();
    }
    @

    Please let me know what I need to change in my code.

    Thank You



  • Perhaps you should also listen on the second channel of QProcess: standard Error. It may tell you more on what is going wrong.



  • @connect(myProcess,SIGNAL(readyReadStandardError()),this,SLOT(errorOut()));

    void MainWindow::errorOut()
    {
    std::cout<<"Hello\n";
    ui->lineEdit->setText("In errorOut Function");
    QByteArray newData = myProcess->readAllStandardError();

    std::cout<<newData.data();
    }@

    Still getting the same output
    QProcess::start: Process is already running

    Also I tried to debug and found that the errorOut() function is never get hit.



  • If you get that error message "Process is already running", the the process is still running. For an unknown reason your python process did not end yet.

    You might want to stop a running process with "QProcess::terminate() ":http://doc.qt.nokia.com/4.7/qprocess.html#terminate or, as a last resort, "QProcess::kill() ":http://doc.qt.nokia.com/4.7/qprocess.html#kill. Check the "state":http://doc.qt.nokia.com/4.7/qprocess.html#state before.

    Better solution would be to make your script terminate automatically.



  • Ive had this same problem and this was just answered for me on the #Qt

    You will need to execute the cmd.exe with /c which will start the python script with the proper associated interpreter.

    @
    QString command("cmd.exe");
    QStringList args;
    args << "/c" << "c:/Test.py";
    @

    One other thing to remember is that not all extensions are executable and you must add them to the PATHEXT list.

    @
    echo %PATHEXT%
    set PATHEXT=%PATHEXT%;.PY
    @

    I also read about QProcess::setNativeArguments added in qt 4.7 which is for windows arguments.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.