2017-12-24 14 views
0

사용자가 버튼을 누르면 매초마다 이미지가 변경되는 주 이미지가있는 GUI (대부분 시뮬레이션)가 작성됩니다 매번 업데이트 된 이미지를 표시 할 수 있습니다 (업데이트는 실제로 여러 가지를 부모 이미지 위에 페인팅하는 것입니다). 테스트를 위해, 시뮬레이션의 10 단계에 대해 모델 변경과 그림 업데이트를 수행하는 '시작 시뮬레이션'슬롯에서 실행되는 루프가 있습니다.PyQt5에서 시뮬레이션 실행 - 시뮬레이션이 끝날 때까지 QGraphicsScene이 업데이트되지 않음

따라서 중앙 이미지는 10 번 업데이트해야합니다. 그러나 콜백이 반환 될 때 중 하나만 시간이 끝까지 업데이트됩니다. 내 기본 모델은 각 단계에서 올바르게 업데이트되며 마지막에 표시되는 이미지는 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() 

여기에 몇 가지 무 조작 코드가있을 수 있습니다 : 자기는 (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'를 사용하여 초당 시뮬레이션 코드를 호출하십시오. – hyde

+1

'time.sleep (1)'을'loop = QEventLoop()' 'QTimer.singleShot (1000, loop.quit)' 'loop.exec _()' – eyllanesc

답변

1

기본적으로 Qt 이벤트 처리는 동 기적으로 수행됩니다. 즉, 프로그램이 특정 슬롯에있는 동안 이벤트를 처리하지 않습니다. self.map_view.update()은 일정하게 이벤트를 이벤트 대기열로 푸시합니다. 그러나 이러한 이벤트는 처리되지 않습니다.

다음은 오랜 계산 동안 Qt 애플리케이션을 응답으로 유지하는 다양한 접근법을 설명하는 오래된 Qt 문서입니다.

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

+0

으로 변경하십시오. 다른 기사와 함께, 내 문제를 해결하는 데 도움이되었습니다. 감사! – user3822171

관련 문제