2012-01-01 6 views
0

의 이미지를 QLabel에 표시해야하는 프로그램을 작성 중입니다. 이미지는 서버에서 전송됩니다. 첫째, 연결 및 서버로부터 데이터 수신에 대한 책임이있는 스레드가 있습니다. 데이터가 수신되면 소켓 스레드는 updateImage(Imagedata) 슬롯에 연결된 gotNewData(Imagedata) 신호를 보냅니다. updateImage(Imagedata) 슬롯에서 서버에서 얻은 이미지 데이터를 QImage으로 변환하고 QPixmap을 만들고 QLabel으로 설정합니다. 내 문제는, 처리 중에 updateImage(Imagedata) 함수는 소켓이 새 이미지로 다른 패키지를 가져오고로 신호를 반복해서 보냅니다. 소켓 스레드는 이전 신호 호출에 의해 호출 된 함수 updateImage(Imagedata)이 이미 끝났는지 신경 쓰지 않기 때문에 논리적입니다. 내 질문은 : 거기에 몇 가지 기술, 어떻게 내 소켓 스레드를 QWidgetupdateImage(Imagedata) 함수와 동기화 할 수 있습니까?은 서버의 이미지 데이터로 QLabel을 자주 업데이트합니다.

답변

0

분명히 있습니다. 질문은 이전 이미지가 아직 처리되는 동안 새 이미지가 수신되는 경우에 달성하고자하는 것과 정확히 일치하는 것입니다. 새로운 것을 건너 뛰고 끝까지 처리하고 싶다면 호출자와 호출 창을 파괴하는 객체 전송에 blockSignals를 호출하는 것이 좋습니다.하지만 qt는 수신 신호를 차단하는 것을 허용하지 않는 것처럼 보입니다. 성능에 많은 영향을 미치지 않으며 다른 comunication 네트워킹과 혼동하지 않도록 수정하면 레이블을 포함하는 위젯에 프록시 QObject를 만든 다음 moveToThread()를 사용하여 네트워크 스레드로 이동하고 on으로 blockSignals를 사용합니다 이 객체. 당연히이 물체는 실제 신호가 보내지는 것과 같은 서명의 신호를 필요로합니다. 생성 된 객체는 다른 스레드 선호도를 사용하는 동안 논리적으로 GUI 위젯이 소유하고 있으므로 삭제해야합니다.

또 다른 방법은 객체에 bool 변수 processing을 만들고 데이터를 처리하는 경우 true로 설정하는 것입니다. false로 다시 설정하기 전에 QCoreApplication::processEvents();을 호출하면 모든 이벤트가 이벤트 대기열에서 처리됩니다. 귀하의 슬롯에 processing vaiable이 설정되어 있는지 확인하고 무엇이든하는 경우 건너 뛰십시오. 그것은 단순하고 거친 soultion이지만 작동합니다. GUI 스레드에서 processEvents(); (예 : 그와 같은 레이블이 두 개 이상) 다른 이벤트 처리기를 사용하는 경우 일부 레이블이 데이터를 가져 오는 것을 멈출 수 있습니다 (고정).

Qt::BlockingQueuedConnection을 사용하면 네트워킹 스레드가 처리하기 전에 아무것도 수신하지 못하도록 막을 수 있지만 여러 가지 이유로 그다지 나쁜 아이디어는 아닙니다. (그런 경우 동기화하면 왜 전혀 별도의 스레드가 필요합니까?)

+0

사용자가 GUI를 사용할 수 있어야하므로 소켓에 소켓을 넣습니다. 내 경우에는 사용자가 버튼을 누르면 일부 명령이 서버로 전송됩니다. 명령을 보내기 위해 다른 소켓 연결을 사용합니다. 그래서 이미지 리시버 소켓을 스레드에 넣고 사용자 상호 작용을 차단해서는 안됩니다. –

+0

필자는 '그런 식으로 동기화한다면 왜 별도의 스레드가 필요할까요?'라는 의미였습니다. 어쨌든 첫 번째 해결 방법은 좋은 아이디어입니다. –

관련 문제