金曜日, 10月 08, 2010

PyQtでショートカットを使う

PyQtの話というよりQtの話ですよね。Ctrl-QとかCtrl-Wとかでお手軽にGUIプログラムを終了できるようにしたい、という極めて安易なこと考えてみましたが、結構手間がかかりました。

調べるとsetShortcut()という関数があるので、これを使うのが早いと考え、試してみます。

        fileMenu = PyQt4.QtGui.QMenu("&File", self)
        self.action_close = fileMenu.addAction("&Close")
        self.action_close.setShortcut("Ctrl+W")
        self.menuBar().addMenu(fileMenu)
        self.connect(self.action_close, PyQt4.QtCore.SIGNAL("triggered()"), self.quit)

    def quit(self):
        sys.stdout.write("close.\n")
        qApp.quit()
一応できたにはできました。ここで、一見メニュへの登録は不要な様に見えるので取り除いてみますが、残念ながら動きません。
        self.action_close = PyQt4.QtGui.QAction("&Close", self)
        self.action_close.setShortcut("Ctrl+W")
        self.connect(self.action_close, PyQt4.QtCore.SIGNAL("triggered()"), self.quit)
できればメニュなしでもショートカットが使えるようにしたいと思います。悩んだ結果、キーボードイベントを捕まえることで解決を図りました。
#!/usr/bin/env python
# -*- coding: utf-8 -*-

# for command-line arguments
import sys

# Python Qt4 bindings for GUI objects
import PyQt4.QtGui

class ApplicationWindow(PyQt4.QtGui.QMainWindow):
    def __init__(self):
        PyQt4.QtGui.QMainWindow.__init__(self)
        self.setWindowTitle("test")

        fileMenu = PyQt4.QtGui.QMenu("&File", self)
        self.action_close = fileMenu.addAction("&Close")
        self.action_close.setShortcut("Ctrl+W")
        self.menuBar().addMenu(fileMenu)
        self.connect(self.action_close, PyQt4.QtCore.SIGNAL("triggered()"), self.quit)

    def quit(self):
        sys.stdout.write("close.\n")
        qApp.quit()

    def keyPressEvent(self, ev):
        if ev.key()==PyQt4.QtCore.Qt.Key_Q:
            if (ev.modifiers() and PyQt4.QtCore.Qt.ControlModifier):
                sys.stdout.write("quit.\n")
                qApp.quit()

# Create the GUI application
qApp = PyQt4.QtGui.QApplication(sys.argv)

# Create the Matplotlib widget
mpl = ApplicationWindow()
# show the widget
mpl.show()

# start the Qt main loop execution, exiting from this script
# with the same return code of Qt application
sys.exit(qApp.exec_())

意外にもキーボートイベントからのCtrl-Q押下の捕捉によってメニュへのショートカット(Ctrl-W)が潰される事はなく、共存して動作します。QMainWindow自体に独自のキーボードイベントはないと思いますし(あくまでも推測)、子ウィジェットからキーボードイベントが伝搬されていることが期待できるならば、この対応で問題はないかなと思うのですけど、どうなんでしょう?

0 件のコメント: