Running a Qt application with Ctrl-B

38 views
Skip to first unread message

reinhard...@googlemail.com

unread,
Aug 25, 2015, 6:26:58 AM8/25/15
to leo-editor
May be this is a stupid question:
I'm trying to import a large Qt application into Leo. For testing, I created a script in a single node with the headline '@clean QtTest.pyw)' and the following body:

@language python
@tabwidth -4

import sys

from PyQt5.QtCore import QObject
from PyQt5.QtWidgets import QApplication, QWidget

class Application(QWidget):
   
   
def __init__(self):
   
       
QObject.__init__(self)
       
self.setGeometry(100, 100, 400, 300)
       
self.setWindowTitle('QtTest')
           
if __name__ == '__main__':
    app
= QApplication([])
    form
= Application()
    form
.show()
    sys
.exit(app.exec_())

From the command line, this script runs without problems (using 'python QtTest.pyw').
But if I try to execute the script in the node (using Ctrl-B), Leo disappears, the Qt window is opened and immediately closed. I want Leo stay visibly in the background and the Qt window in the foreground until it is closed explicitly.

What do I miss?

Terry Brown

unread,
Aug 25, 2015, 10:18:40 AM8/25/15
to leo-e...@googlegroups.com
On Tue, 25 Aug 2015 03:26:58 -0700 (PDT)
reinhard...@googlemail.com wrote:

> May be this is a stupid question:
> I'm trying to import a large Qt application into Leo. For testing, I
> created a script in a single node with the headline '@clean
> QtTest.pyw)' and the following body:
>
> @language python
> @tabwidth -4
>
> import sys
>
> from PyQt5.QtCore import QObject
> from PyQt5.QtWidgets import QApplication, QWidget
>
> class Application(QWidget):
>
> def __init__(self):
>
> QObject.__init__(self)
> self.setGeometry(100, 100, 400, 300)
> self.setWindowTitle('QtTest')
>
> if __name__ == '__main__':
> app = QApplication([])
> form = Application()
> form.show()
> sys.exit(app.exec_())

Leo executes Python code in the interpreter that runs Leo. Seeing that
interpreter has a QApplication, you can't have another. Also, if it's
executing the `if __name__ == '__main__':` block, and it seems like it
is, sys.exit() is going to bring everything to an end.

So, to execute from Leo, just do the form = Application();
form.show() part, avoid the `app =` and sys.exit() parts.

Or make a separate script button like:

import os
os.system("python /path/to/QtTest.pyw")

(or use subprocess.Popen, but if you just want the app to run to see
the impact of changes, os.system is probably sufficient)

Cheers -Terry

Edward K. Ream

unread,
Aug 25, 2015, 11:15:20 AM8/25/15
to leo-editor
On Tue, Aug 25, 2015 at 5:26 AM, <reinhard...@googlemail.com> wrote:
May be this is a stupid question:

​There are no stupid questions, only stupid answers :-)
 

​Leo is already a QApplication, so you don't want another copy.

Whenever something weird happens, be sure you run Leo from a console window.  Here is what I see (and all I see) when I run your program:

    QCoreApplication::exec: The event loop is already running

If you want to run an application from within Leo, use g.app.gui.qtApp instead of creating another app.  Depending on how complex the app is, this may take some doing.

The other alternative is to run the original code in an external process, completely separate from Leo.  Here is one way:

path = r'c:\users\edreamleo\test\QtTest.py'
assert g.os_path_exists(path)
g.executeFile(path)


HTH.

Edward

reinhard...@googlemail.com

unread,
Aug 25, 2015, 11:27:09 AM8/25/15
to leo-editor
@Terry and Edward

Thank you both for your detailed answers!
I tried both methods, and both work like a charm.

Reinhard

 
Reply all
Reply to author
Forward
0 new messages