5

SqueezeBoxコントローラーアプリであるSqueezePlayでステータスをチェックする音楽プレーヤーを作成しています。簡単に言うと、スレッドを使用してSqueezeplayのステータスを5秒ごとにチェックしています。曲のタイトルが変更された場合は、ラベル(Qlabel、アルバムアートワーク(QPixmap)など)を更新させます。ただし、スレッドを介して更新するように依頼すると、GUIスレッドの外部でピックスマップを使用するのは安全ではありません。

どうすればスレッド化を実行できますが、それでもQPixmapを設定できますか?

サンプルコード:

#self.sq.getArtwork() returns variable with the image
coverArt = self.sq.getArtwork()
coverPixMap = QtGui.QPixmap()
coverPixMap.loadFromData(coverArt)
self.albumArt.setPixmap(coverPixMap)

どうもありがとう!

更新: Emitで次のことを試しましたが、機能しません。誰かが私が間違っていることを確認できますか?

def setNewArtwork(self, image):
    coverPixMap = QtGui.QPixmap()
    coverPixMap.convertFromImage(image)
    icon = QtGui.QIcon(coverPixMap)
    item.setIcon(icon)

def getNewArtwork(self):
    coverArt = self.sq.getArtwork()
    icon = QtGui.QImage(coverArt)
    self.emit(QtCore.SIGNAL('setNewArtwork(QImage)'), icon)
4

4 に答える 4

7

すべてのグラフィカルQt操作は、メインスレッドで実行する必要があります。他のスレッドは、Qtグラフィカル操作(おそらくピックスマップを含む)を呼び出すことを実際には許可されていません。

彼らはメインスレッドにQt信号を発することができました。または、単に(Linuxの場合)パイプに書き込み、メインスレッドにそのパイプへの入力を待機させます。

もちろん、必要な信号(およびスロット)を定義する必要があります。signals:C ++コードでは、それらに(または)のマークを付ける必要があり、C++コードはmocslots:によって処理される必要があります。Pythonの対応物が何であるかわかりません(おそらくPythonのリフレクション機能で十分かもしれませんが、私は本当に知りません)。次に、キュー接続を使用して信号をスロットに接続する必要があります。Pythonでそれを行う方法がわかりません。

于 2011-12-27T21:03:24.897 に答える
4

Pythonでシグナルを出力する方法に関する質問に答えるには:

C ++とは異なり、 (Qt信号ではなく)ユーザー定義のPyQt信号を送信する場合は、署名を省略する必要があります。

したがって、信号を発信するには、次のようにします。

thread.emit(QtCore.SIGNAL('newArtworkAvailable'), icon)

そして、信号に接続するには、次のようにします。

widget.connect(thread, QtCore.SIGNAL('newArtworkAvailable'),
               widget.setNewArtwork)

そして明確にするために:

これが機能するためには、非GUIスレッドが信号を送信する必要があります。信号はメインのGUIスレッドの適切なウィジェットによって受信されます。非GUIスレッドでの作成はQImage問題ありませんが、メインスレッドの外部でGUI関連のメソッドを呼び出そうとしないでください。

注意

ここでは古いスタイルの信号構文を使用しました。これは、使用しているように見えるためです。ただし、PyQtの新しいスタイルの信号とスロットのサポートは、はるかに柔軟でPythonicであるため、確認することをお勧めします。

于 2011-12-28T00:08:39.560 に答える
1

おそらく、すべての描画ジョブをメインスレッドに送信する必要があります。

于 2011-12-27T21:07:18.000 に答える
0

私はsthを試しましたが、ベルが鳴るかどうか教えてください。私も同様のsthを実行しました(ただし、しばらくの間Pythonから遠く離れているので、間違いを犯した可能性があります。そうであれば、申し訳ありません)。

class MyThread(QThread, ui):
    def __init__(self, ui):
        super(MyThread, self).__init__(self)
        self.ui = ui

    def run(self):
       coverArt = self.ui.getArtwork()
       coverPixMap = QtGui.QPixmap()
       coverPixmap.convertFromImage(QtGui.QIcon(coverArt))
       icon = QtGui.QImage(coverPixMap)
       self.ui.item.setIcon(icon)  // set icon
       self.ui.singerLabel.setText("Singer")  // update label 

# your gui class
class YourInterface(QtGui.QWidget):
    def __init__(self):
       QtGui.QWidget.__init__(self)
        myThread = MyThread(self)
        self.myButton.clicked.connect(myThread.run)
        # all other stuff
        #
        #
于 2011-12-27T23:05:29.403 に答える