Menu

PythonQtScriptingConsole

Help
2015-10-29
2015-11-12
  • Joerg Kreuzberger

    Hi!

    i was evaluating PythonQtScriptingConsole to get an "interactive" python console into my Qt Gui Application.
    Many thinks work excelect, but i have some issues

    • I cannot terminate long running actions with Ctrl+C
    • i cannot control script workflow with key presses.

    So even if i start my gui app, all keyboard events are handled by the tty console from which i startet my app. Here Ctrl-C typed gets handled by the PythonQtScriptingConsole.

    Which would be the best way to extend the PythonQtScripingConsole to get "keyboard" handling into the console? Or any other way (events from menu for example) to control the scripts (at least abort like with Ctrl-C).

    Another issue that on long running scripts, the whole application freezes, not just the console window. Should an console instance be threaded to avoid this? But normale the widgets require to run in the main thread....

    System is Linux, Qt 4.8 and running with Anaconda(2) 2.3

    Thanks for any hints....

     
  • Florian Link

    Florian Link - 2015-10-29

    I don't know how interruption could be implemented, since it would require to process Qt events inside of the Python interpreter loop to be able to break the code. On the shell, the Control-C triggers an interrupt, which the interpreter handles, but there is no such think in Qt.
    Using an extra thread is difficult, because the Qt gui needs to run in the main theead an because PythonQt is not thread-safe.

    Buf if someone knows a solution, please speak up, I would also be interested in this.

     
  • Brian

    Brian - 2015-11-04

    I've been also getting into this same problem recently. There's many topics about threading support in dicussion without clear answer, or not possible at the end.
    I personally think the problem is people (including myself) misused the library. PythonQt provides the way to manipulate the Qt GUI, and most of people like to include too many complex packages into the embed python system itself. For convenience you can write a script and you done a complex function, it takes a lot of time if you try to work with C++.
    Python is single threaded, PythonQt is using singleton pattern. And while maincontext is binding into main gui thread, it's hard to release the gui if you are not using signal-slot binding. Otherwises, currently evalFile or evalScript is using the python eval() interface, it's hard to debug or tracing time-consumed programs.
    I tried to move main context to other thread but it breaks the signal-slot in python context.
    Using thread in main python context won't work neither.
    Maybe I have to try eval line-by-line and emit the signal to return back to Qt event loop. As I checked with Blender scripting environment, safe-threading is also an issue when doing time-consumed process.

     
    • Joerg Kreuzberger

      For me it works to execute my scripts in an thread as long as they have no gui dependency (using QtGui Features in the script or matplotlib e.g.)
      i then can control script e.g. by adding objects from my gui application in the python context and control script workflow
      e.g i have a Debug Object in my gui application.
      in the scripts i then can e.g. stop my script at a given point.
      I then start a second script, using the SAME context as the currently stopped script and can investigate all variables

      e.g.

      Script 1:

      c=1
      while c < 10:
      Debug.stopScript()
      c+=1

      Script2:
      print c

      So everythime Script 1 stops, i execute script 2 and can see the current value of c
      From the gui i have an slot that triggers to continue in my Debug Object.

       
  • Joerg Kreuzberger

    For the PythonQtScriptingConsole i found a solution by adding an
    RedirectStdInCallback Handler

    i derive a class from PythonQtScriptingConsole and in the ctor i register an callback

    PythonQtInputChangedCB *callback = pythonQtInputCallback;
    PythonQt::self()->setRedirectStdInCallback(callback, this);
    PythonQt::self()->setRedirectStdInCallbackEnabled(true);

    namespace
    {
    QString pythonQtInputCallback(void that)
    {
    return ((PythonQtScriptingConsole
    )that)->waitForUserInput();
    }
    }

    This idea came from the PythonQt documentation, i found an example on how to use it
    https://github.com/Orochimarufan/PythonQt/tree/master/examples/NicePyConsole

    Attached my modifications to the PythonQtScriptingConsole

    So keypress handling is now catched in the console directly (but not yet Ctrl+C)
    For use of PDB in the console i will use the Pdb(stdin=) to redirect it the same way

     

    Last edit: Joerg Kreuzberger 2015-11-06
  • Joerg Kreuzberger

    Found serveral solutions for several issues:
    - matloblib: i confgiure matloblib not to use qt. this is selected by default. This "interacts" with my main gui qt and i cannot run the script in threaded context. If i configure matplotlib to use another gui system or use image files only, i cant use matloblib directly.
    e.g.

    import matplotlib as mpl
    mpl.use('tkagg')
    import matplotlib.pyplot as plt

    plt.plot([1,2,3])
    plt.show()

    • After updating with python3 und newest pythonqt3 i am able to debug my scripts when execute them with evalString():
    • i add before the script context
      import pdb
      pdb.set_trace()
    • i use the redirect stdin like from the example above
    • now pdb executes the script and if user input requires, it waits e.g. for toolsbars pressed (e.g. to contiue, next, step into, print variables and so on)
    • for readOnly actions i attach a second thread to the actually started context.
    • no further actions for pdb have to be made
     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.