1

私はpython 3.3.3とpyqt5でプログラムを書いています。多くの信号とスロットを問題なく接続しました。これは問題を引き起こしています。私のコードは次のとおりです。

   def populateVendorAndModelComboBoxes(self, vendorComboBox, modelComboBox):
    dictVendors = {}
    #for rclass in sorted(list(directory.DRV_TO_RADIO.values())):
    for rclass in list(directory.DRV_TO_RADIO.values()):
        if not issubclass(rclass, chirp_common.CloneModeRadio) and \
                not issubclass(rclass, chirp_common.LiveRadio):
            continue

        if not rclass.VENDOR in dictVendors:
            dictVendors[rclass.VENDOR] = []

        dictVendors[rclass.VENDOR].append(rclass)

    vendorComboBox.addItems(sorted(list(dictVendors)))

    def _vendorChanged(vendorCBox, vendorsDict, modelCBox):

        modelsList = vendorsDict[vendorCBox.currentText()]

        added_models = []

        modelCBox.clear()
        for rclass in modelsList:
            if rclass.MODEL not in added_models:
                added_models.append(rclass.MODEL)
        print("adding to modelCB")
        modelCBox.addItems(sorted(added_models))
        print("Done adding to modelCB")

    vendorComboBox.currentTextChanged.connect(_vendorChanged(vendorComboBox, dictVendors, modelComboBox))
    _vendorChanged(vendorComboBox, dictVendors, modelComboBox)

このコードは、コンボボックスにベンダーとモデルを入力します。ベンダー コンボボックスは起動時に読み込まれます。モデル コンボボックスには、ベンダーごとに異なるデータが入力されます。ユーザーが別のベンダーを選択するたびに、モデル コンボボックスを別のリストで更新する必要があります。

何が起こるべきか:

メソッド populateVendorAndModelComboBoxes が呼び出されると、プログラムの最初の部分でベンダー リストがベンダー コンボボックスに配置されます。次に、currentTextChanged シグナルと _vendorChanged スロットの間で接続が確立されます。次に、_vendorChanged 関数を最初に呼び出して、Model コンボボックスをセットアップする必要があります。それ以降、ユーザーが新しいベンダーを選択するたびに、_vendorChanged 関数を呼び出す必要があります。

何が起こっている:

currentTextChanged 信号と _vendorChanged スロットの間で接続が確立されると、_vendorChanged 関数がすぐに呼び出されます。_vendorChanged 関数をすぐに呼び出さないでください。これは、他のシグナル/スロット接続では発生しません。_vendorChanged 関数がエラーなしで実行され、実行ポイントが vendorComboBox.currentTextChanged.connect.... ステートメントに戻り、すぐにエラー TypeError: 引数 1 に予期しない型 'NoneType' があります。

接続を行うステートメントをコメントアウトすると、プログラムはエラーなく動作します。ベンダー コンボボックスにはベンダーが入力され、モデル コンボボックスにはリストの最初のベンダーのモデルが入力されます。これは、_vendorChanges コードが正しく機能していることを示しています。

2 つの質問があります。connect ステートメントによって _vendorChanged 関数がすぐに実行されるのはなぜですか? エラーメッセージの原因は何ですか?

4

3 に答える 3

0

優れた答えですが、この説明を追加したいだけです:

やっている

vendorComboBox.currentTextChanged.connect(_vendorChanged(vendorComboBox, dictVendors, modelComboBox))

するのと同じです

obj = _vendorChanged(vendorComboBox, dictVendors, modelComboBox)
vendorComboBox.currentTextChanged.connect(obj)

objこれは関数ではなく、3 つのパラメーターを使用して関数を呼び出した結果であることがわかり_vendorChangedます。これは、シグナルがすぐに起動され、それによって関数が呼び出されたという印象を受けることを意味しますが、実際には、指示どおりに関数が実行されているだけです。2 番目の問題は、_vendorChanged何も返さないため、obj が実際には None であることです。信号を None に接続しようとしているため、このエラーが発生します。解決策は他の回答で与えられます。

于 2014-02-25T20:09:40.830 に答える
0

このエラーは、関数オブジェクト自体ではなく、関数呼び出しの結果(この場合は )に接続しようとしたために発生します。Noneもちろん、これは関数がすぐに実行される理由も説明しています。

次のように、関数呼び出しを でラップする必要がありますlambda

    vendorComboBox.currentTextChanged.connect(
        lambda: _vendorChanged(vendorComboBox, dictVendors, modelComboBox))
于 2014-02-25T05:37:34.710 に答える