いいかげん日記

思いついたことをただひたすら書き殴るいいかげんな日記です。

【Python × PyQt5】 google spreadsheet viewerを作る。(その5:ショートカットキーを割り当てる)

前回までのお話】

退屈なことはPythonやらせようとしていた私は、ある日、偶然PyQtに出会い、「自分で作ったアプリケーションを自分で操作するのも悪くないのではないか?」と考え始める。

そして『っぽい』アプリケーションを作るべく、茨の道を歩むことになった。

ウィンドウを作り、そこにテーブルとボタンを載せ、ボタンに機能をあたえることに成功したことで気を良くした私は、まだ全体像すら定まっていないプログラムに、ショートカットキーを割り当てることにしたのであった。。

【今回の課題】

前回、見事ボタンに機能を与えることに成功して、もう既に『っぽい』アプリケーションにかなり近づいた感覚になっています。

アプリケーションであるならば、やはりユーザビリティには気を遣うべきでしょう。

ユーザビリティ向上のために重要なことは、、、そう!ショートカットキーです!

ということで、今後の開発と検証作業を行うなかで、どうしたって繰り返さざるを得ない「アプリケーションの終了」のショートカットキーを作っていきます。

【コード】

では、早速コードを書いていきます。

import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class MyMainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)

        quitShortcut = QShortcut(QKeySequence("Esc"), self)
        quitShortcut.activated.connect(self.close)

class SpreadSheetWidget(QWidget):
    def __init__(self, row, col, parent=None):
        QWidget.__init__(self, parent=parent)
        self.setup_ui(row, col)

    def setup_ui(self, row, col):
        self.spreadsheet = QTableWidget(row, col)

        layout = QVBoxLayout()
        layout.addWidget(self.spreadsheet)

        self.setLayout(layout)

    def add_row(self):
        self.row_position = self.spreadsheet.rowCount()
        self.spreadsheet.insertRow(self.row_position)

    def add_col(self):
        self.col_position = self.spreadsheet.columnCount()
        self.spreadsheet.insertColumn(self.col_position)

class AddButtonWidget(QWidget):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent=parent)
        self.setup_ui()

    def setup_ui(self):
        self.add_button_row = QPushButton('Add row', parent=self)
        self.add_button_col = QPushButton('Add col', parent=self)

        layout = QHBoxLayout()
        layout.addWidget(self.add_button_row)
        layout.addWidget(self.add_button_col)

        self.setLayout(layout)

def main():
    app = QApplication(sys.argv)

    main_window = MyMainWindow()
    panel = QWidget()
    layout = QVBoxLayout()
    spreadsheet_widget = SpreadSheetWidget(3,4,parent=panel)
    add_button_widget = AddButtonWidget(parent=panel)

    layout.addWidget(spreadsheet_widget)
    layout.addWidget(add_button_widget)

    panel.setLayout(layout)
    main_window.setCentralWidget(panel)

    add_button_widget.add_button_row.clicked.connect(spreadsheet_widget.add_row)
    add_button_widget.add_button_col.clicked.connect(spreadsheet_widget.add_col)

    main_window.show()
    app.exec_()

if __name__ == '__main__':
    main()


----私なりの説明----

さて、今回は何が変わったかというと、、

class MyMainWindow(QMainWindow):
    def __init__(self, *args, **kwargs):
        QWidget.__init__(self, *args, **kwargs)

        quitShortcut = QShortcut(QKeySequence("Esc"), self)
        quitShortcut.activated.connect(self.close)

あぁ、いきなり変わってますね。

'MyMainWindow' なるクラスが定義されています。

クラスが定義されてるってことは、'main()' 関数でも使われているはずなんだけど、、

    main_window = MyMainWindow()

はい、ありますね。

前回の 'main_window' は 'QMainWindow()' のインスタンスだったはずです。

ということを頭に入れてクラスの定義に戻ると、、

class MyMainWindow(QMainWindow):

なるほど。'MyMainWindow' は 'QMainWindow' を継承したクラスなんですね。

で、その次の行は、、

    def __init__(self, *args, **kwargs):

んーと、引数に'self' 以外の '*args' と '**kwargs' ってのがいるけど、どなた様?


・・・いや、わからん。


まぁ、いいか。次進もう。

        QWidget.__init__(self, *args, **kwargs)

うわっ、ここにもいるよ。。

知らん。次!(あれ?ってか、これ 'QMainWindow' のコンストラクタじゃないじゃん。これは通っちゃうんだ。。ようわからんなぁ…)

        quitShortcut = QShortcut(QKeySequence("Esc"), self)
        quitShortcut.activated.connect(self.close)

さてさて、ようやく本題のショートカットキーの部分に到着。

最初の行で、'QKeySequence("Esc")' と 'self' を引数に持つ 'QShortcut' メソッドのインスタンスに 'quitShortcut' なる名前をつけていますね。

引数から察するに、「 この(self)クラス(つまり、'MyMainWindow' クラス)では、エスケープ(Esc)キーをショートカットキーとして認識しますよ。で、以後、このことを 'quitShortcut' と呼ぶからね!」と言っているのではなかろうか。

次の行では、前回見てたやつがいますね。たぶん、

'quitShortcut' がアクティブになる(= Escキーが押される → 「このキーは… あ!ショートカットキーだ!」となる)ことは、この(self)クラスを閉じる(close)メソッドを呼び出すことにしましょう。

っていうことでしょう、どうせ。(適当)


ということなので、これクラスのインスタンスである 'my_main_window' が 'main()' 関数の中で使われていて、その上にテーブルウィジェットとボタンウィジェットが乗っかっているので、Escキーを押せば画面が消えるはず。

【外観】

このコードを実行するとこんなウィンドウが出ます。

f:id:theta_proto:20180828215945j:plain

はい、前回と変わりません。

そしてEscキーを押すと、、、














ほら、消えた!    (to be continued...)