4

こんにちは、以下のような 2 つのボタンを備えた単純な GUI があります。ボタンがクリックされると、ボタンのテキストを変更するメソッドを作成しました。書き換えることなくメソッドを任意のボタンに適用するために、メソッドをモジュール化して一般化したいと考えています。以下の例では、新しいメソッドを定義せずに、printWow() メソッドをボタン 2 に適用するにはどうすればよいでしょうか?

import sys
from PyQt4.Qt import *

class MainWindow(QMainWindow):
    def __init__(self, *args):
        QMainWindow.__init__(self, *args)
        self.cw = QWidget(self)
        self.setCentralWidget(self.cw)
        self.btn1 = QPushButton("Click me", self.cw)
        self.btn1.setGeometry(QRect(50, 50, 100, 30))
        self.btn1.clicked.connect(self.printWow)

        self.btn2 = QPushButton("Click me", self.cw)
        self.btn2.setGeometry(QRect(50, 20, 100, 30))
        self.btn2.clicked.connect(self.printWow)

    def printWow(self):
        self.btn1.setText("WoW")

if __name__ == "__main__":
    app = QApplication(sys.argv)
    myapp = MainWindow()
    myapp.show()
    sys.exit(app.exec_())
4

2 に答える 2

1

基本的に、関数を「より一般的な」ものにするということは、さまざまなユースケースでバリアントとインバリアントを識別することを意味します。あなたの例では、バリアントは呼び出したいオブジェクトになりsetText()、最終的にはテキスト自体になるため、「ジェネリック」関数は次のようになります。

def printText(self, target, text="wow"):
    target.setText(text)

次に、これらの引数を に渡すことができないためconnect()(少なくとも、この例のためにこれが当てはまると仮定しましょう)、ジェネリック関数への参照と引数を、引数なしで呼び出すことができるものでラップする必要があります。これは「部分評価」の例であり、最も単純な形式では、次のものが必要lambdaです。

class MainWindow(QMainWindow):
    def __init__(self, *args):
        QMainWindow.__init__(self, *args)
        self.cw = QWidget(self)
        self.setCentralWidget(self.cw)
        self.btn1 = QPushButton("Click me", self.cw)
        self.btn1.setGeometry(QRect(50, 50, 100, 30))
        self.btn1.clicked.connect(lambda: self.printWow(self.btn1))

        self.btn2 = QPushButton("Click me", self.cw)
        self.btn2.setGeometry(QRect(50, 20, 100, 30))
        self.btn2.clicked.connect(lambda: self.printText(self.btn2, "Yay!"))

    def printText(self, target, text="wow"):
        target.setText(text)

上記の例では、余分な複雑さからあまり得られないことに注意してください。すべてをラムダに入れることもできます。

self.btn1.clicked.connect(lambda: self.btn1.setText("Wow"))
self.btn2.clicked.connect(lambda: self.btn2.setText("Yay !"))

しかし、もっと複雑なことを考えていると思います...

「モジュール性」について言及しているので(少なくともタイトルで)、「モジュール化」コードの真の鍵は、必ずしも(または少なくともそれだけでなく)一般的なコードを除外することではなく、主にコードを適切に分離されたモジュールに分割することです。それぞれが明確で明確な責任を持っています。標準的な例は、UI コードを「ドメイン」コードから分離することです。このコードは、実際の仕事を行い、UI が存在することさえまったく知らないはずです...

于 2015-10-12T11:57:31.927 に答える