2017-12-24 21 views
0

私は、ユーザーがボタンを押したときにこのイメージが1秒ごとに変化するようなメインイメージのGUIを持つアプリケーション(主にシミュレーション)毎回更新された画像を表示する(更新は実際には様々なものを親画像に塗りつぶすだけである)。ちょうどテストするために、シミュレーションの10ステップのモデルの変更と画像の更新をすべて行う「スタートシミュレーション」スロットでループを実行します。PyQt5でシミュレーションを実行する - シミュレーションが終了するまでQGraphicsSceneが更新されない

したがって、中央の画像は10回更新する必要があります。ただし、コールバックが返されたときに最後に1つだけ時間が更新されます。私の基本的なモデルは各ステップで正しく更新されており、最後に表示される画像は10番目のタイムステップの正しい画像です。

私はQtが新しく、問題は何かウィジェット/アップデートに関係していると確信していますが、私は運が全くありませんでした。

コールバック私はスタートシミュレーションボタンに登録しています。このボタンはイメージ更新プロセスを開始します。私がしたので、ここでいくつかのノーオペレーションコードがあるかもしれません

def simulation_step(self): 
    self.load_map() 
    self.draw_dot() 


def load_map(self): 
    self.map_image = QImage("ancient_map_seed1.png") 
    self.current_pixmap = QPixmap.fromImage(self.map_image) 

    self.map_scene = QGraphicsScene(self) 
    self.map_graphics_item = self.map_scene.addPixmap(self.current_pixmap) 
    self.setScene(self.map_scene) 


def draw_dot(self): 
    founder_pop = self.map_objects.populations[0] 
    print("Height: +" + str(founder_pop.x)+ "; width: " + str(founder_pop.y)) 
    dot = QGraphicsPixmapItem(QPixmap.fromImage(self.red_dot), parent = self.map_graphics_item) 
    dot.setPos(founder_pop.x, founder_pop.y) 
    new_x = founder_pop.x + random.randint(-5, 5) 
    new_y = founder_pop.y + random.randint(-5, 5) 
    self.map_objects.populations[0].x = new_x 
    self.map_objects.populations[0].y = new_y 
    self.map_objects.population_matrix[new_x][new_y] = self.map_objects.population_matrix[founder_pop.x][founder_pop.y] 
    self.map_objects.population_matrix[founder_pop.x][founder_pop.y] = self.map_objects.PopulatedTile() 

:selfは(QGraphicsViewのサブクラスである)map_viewクラスのQMainWindow

def start_simulation(self): 
    self.map_view.place_initial_population(250, 250) 
    for i in range(1, 10): 
    self.map_view.simulation_step() 
    self.map_view.update() 
    time.sleep(1) 

関連機能のサブクラスであります私は何らかの形で関係していると思われる機能を試していました。私はコンテキストのためにこれらの関数に少しコードを移しました。

ありがとうございます!

+1

は、それは時々() ''ループ内QtWidgets.qApp.processEventsを行うのに役立ちます。 – ekhumoro

+1

Qtイベントループでsleepを使用しないでください( 'processEvents'でも、イベントループコードを再入力し、問題の原因となる状況があります)。代わりに、 'QTimer'を使用して、1秒に1回シミュレーションコードを呼び出します。 – hyde

+1

'time.sleep(1)'を 'loop = QEventLoop()'に変更する 'QTimer.singleShot(1000、loop.quit)' 'loop.exec _()' – eyllanesc

答えて

1

デフォルトでは、Qtイベント処理は同期的に行われます。つまり、プログラムが特定のスロット内にある間は、イベントは処理されません。 self.map_view.update()は、ただちにredrawのイベントをイベントキューにプッシュします。これらのイベントは処理されません。

長い計算中にQtアプリケーションを応答し続けるためのさまざまなアプローチについて議論している古いQtの記事です。

https://doc.qt.io/archives/qq/qq27-responsive-guis.html

+0

良い記事と、私の問題を解決するのに役立ちました。ありがとう! – user3822171

関連する問題