Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?
@Hanjin_Liu

JupyterからQtアプリケーションを動かす

はじめに

Jupyter NotebookやJupyter QtConsoleでQtのQWidgetQMainwindowなどをshow()で動かそうとするとイベントループの関係でフリーズするか"Kernel died"になります。マジックコマンド%gui qtでこれは解決しますが、毎回これを実行するのもだるいし、同じコードブロックで実行すると意味がないとか結構謎な挙動を示します。

ここでは、%gui qtの実行を、Qtウィジェットの__init__内で勝手にやってくれる便利な方法を紹介します。

ポイント

  • QWidget.__init__の前にQApplicationを走らせる。
  • QApplicationを走らせる前に%gui qtを走らせる。
  • Garbage collectionでQApplicationが持っていかれないようにする。

方法

まずは%gui qtを走らせてからQApplicationを立ち上げる関数です。

from qtpy.QtWidgets import QApplication

APPLICATION = None

def gui_qt():
    try:
        from IPython import get_ipython
    except ImportError:
        get_ipython = lambda: False

    shell = get_ipython()

    if shell and shell.active_eventloop != "qt":
        shell.enable_gui("qt")
    return None

def get_app():
    gui_qt()
    app = QApplication.instance()
    if app is None:
        app = QApplication([])
    global APPLICATION
    APPLICATION = app
    return app

関数gui_qt内でipythonのシェルを取得し、enable_gui%gui qtを実行します。Jupyter以外の環境でも問題ないように、try/exceptや場合分けを慎重に行います。

関数get_appでは、gui_qtを呼んでからQApplicationを走らせます。すでに走っている場合、クラスメソッドQApplication.instanceQApplicationのインスタンスが取得できるので、これがNoneの場合のみQApplication([])で新しく用意します。

最後に、グローバル変数APPLICATIONに残しておくことで、garbage collectionを回避します。


このget_app関数をコンストラクタ内で実行します。ここでまた、app = get_app()のようにQApplicationインスタンスを取っておかないとなぜかフリーズします。

from qtpy.QtWidgets import QMainWindow

class MyWidget(QMainWindow):
    def __init__(self):
        app = get_app()
        super().__init__()

以上で問題なく起動します。例えばmywidgetモジュールにこれがあれば

from mywidget import MyWidget

widget = MyWidget()
widget.show()

だけでOKです。起動したアプリケーションとJupyterが同時に動かせます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?