いいかげん日記

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

【Python × PyQt5】 google spreadsheet viewerを作る。(その3:ボタンを作る)

前回までのお話】

遂に始まった『っぽい』アプリケーション作り。

当初の方針は「外部からデータを取り込み、テーブルに表示する何か」という、非常にざっくりとしたもの。

そして「Google APIを使う」という発想も頭の片隅にもなかったのであった。

【今回の課題】

今回の課題は「画面にボタンを追加する」というもの。

GUIプログラミングをやるからにはボタンの一つも表示させなきゃいかんでしょ」という、設計思想のカケラもないモチベーションに動かされ、早速作ってみました。

ボタンを表示させるだけならそれこそネットにごまんとサンプルコードが転がっていますので、さすがの私もすんなりと表示できましたよ。

【コード】

じゃあ、早速コードに移りましょう。

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

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)

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

    def setup_ui(self):
        self.add_button = QPushButton('Add row', parent=self)

        layout = QHBoxLayout()
        layout.addWidget(self.add_button)

        self.setLayout(layout)

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

    main_window = QMainWindow()
    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.clicked.connect(spreadsheet_widget.add_row)

    main_window.show()
    app.exec_()

if __name__ == '__main__':
    main()

前回のコードに 'AddButtonWidget' クラスを加えて、main()の中でそのインスタンス 'add_button_widget' を生成し、layoutに入れ込むだけ。

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

ボタンを作るだけなら余裕のクリアでしたので、文字数稼ぎに 'AddButtonWidget' クラスを私なりの説明します。(間違いがあればぜひご指摘を!)

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

まず、QWidgetを継承したAddButtonWidgetなるクラスを生成して(1行目)、コンストラクタなるもの定義を宣言する(2行目)。

        QWidget.__init__(self, parent=parent)
        self.setup_ui()

そして、元のQWidgetのコンストラクタを呼び出して(3行目)、self.setup_ui()なるメソッドを呼び出す(4行目)。 正直、私にとって3行目はおまじないです。

想像するに、1行目は「AddButtonWidgetの引数にQWidgetを渡すよ!」ということを示しているだけで、実質的な継承は3行目でやってる、ってことなのかな?

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

        layout = QHBoxLayout()
        layout.addWidget(self.add_button)

        self.setLayout(layout)

で、結局、4行目の 'setup_ui()' って何なのさ? って感じなので、5行目にその定義をします、と宣言する。

6行目以降はその定義で、まず "Add row" って文字が書いてあるボタン(QPushButton)を生成して、それに 'self.add_button' という名前を付ける。(parent=selfっちゅうのもよくわからんのだけど、まぁ入れとく。ここで作ったボタンの親要素はAddButtonWidgetだよ、ってこと?)

そのボタンをどうやってレイアウトしますか?ってのを決めるためにQHBoxLayout()っていうレイアウトの形式を決めたオブジェクトのインスタンス(でいいの?)を作って、それに 'layout' という名前を付ける(8行目)。

9行目で、8行目で作ったレイアウトの中に6行目で作ったボタン 'self.add_button' を入れる。

最後に、'self.add_button' が入ったレイアウトを 'self' (= AddButtonWidget)に適用するよ、と教えてあげたらAddButtonWidgetクラスの完成。

【外観】

実行するとこんなウィンドウが出ます。 f:id:theta_proto:20180827202716j:plain

ただし、この状態では押しても何も起こりません 笑

さて、機能を付けるか。    (to be contenued...)