2016-10-31 6 views
3

여러 qt 응용 프로그램을 컨테이너로만 작동하는 다른 응용 프로그램에 포함하려고합니다.qt 응용 프로그램 내에서 qt 응용 프로그램 실행

응용 프로그램 컨테이너 컨테이너에 전화를 수 있습니다 및 하나 개의 실행 형태의 용기 유틸리티

용기에서 나는 QTabWidget를 가지고 있고,이 QTabWidget 안에 내가있다 (I 리눅스를 사용하고 있습니다) utility1Widget이라는 위젯이있는 탭.

유틸리티 유틸리티 1 위젯의 GUI를보고 싶습니다.

편집 2 : 초기 접근 방식이 잘못되었으므로 나중에 참조 할 수 있도록 노력하겠습니다. 그러나 실제로 구현 된 방법은 분리 된 대답입니다.

나는 utility1Widget의 WID를 얻을 성공없이 시도하고 유틸리티의 시작 시간에 인수로 보내야합니다, 뭔가 같은 다음 utility1Widget를 결과로

utility.cpp

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    int containerWinId; 
    QWidget *parent=NULL; 
    if(argc==2) { 
     containerWinId=atoi(argv[1]); 
     parent = QWidget::find(containerWinId); 
    } 

    MarinaWindowClient w(parent); 

    w.show(); 
    printf("Starting client window. Do you see something?\r\n"); 
    fflush(stdout); 
    return a.exec(); 
} 

비어 있지만 유틸리티 GUI는 아무 데나 나타나지 않습니다.

유틸리티 프로세스는이 방법으로 컨테이너에서 시작됩니다 :

mainContainer.cpp

marinaContainer::mainContainer(QWidget *parent) : 
    QWidget(parent), 
    ui(new Ui::mainContainer) 
{ 
    ui->setupUi(this); 
    WId myWinId=ui->utility1Widget->winId(); 
    char cmd[1000]; 
    sprintf(cmd," %d",myWinId); 
    QProcess *myProcess = new QProcess(this); 
    myProcess->start("utility1", QStringList(cmd)); 

    printf("Client started\r\n"); 
    fflush(stdout); 
} 

감사합니다 !!!!

편집 한 내가 찾기 기능의 결과를 검사하는 부모 변수를 추가하고, 내가 가진 첫 번째 문제는 내가 유틸리티에서, 컨테이너 위젯 ID를 얻을 수 있다는 것입니다 그래서, NULL이다.

+0

이 [링크] (http://stackoverflow.com/questions/17319853/can-qwidgetfind-find-widgets-from-a-different-process)에 따르면 내 접근 방식은 찾기가 쉽지 않으므로 찾기가 쉽지 않습니다. 로컬 윈도우 ids ' – Mquinteiro

+1

네이티브 윈도우 ID를 가지고 있다면 ['QWidget :: createWindowContainer'] (http://doc.qt.io/qt-5/qwidget.html#createWindowContainer)와 ['QWindow :: fromWinId'] (http://doc.qt.io/qt-5/qwindow.html#fromWinId). –

+0

어떤 버전의 Qt를 사용하고 있습니까? –

답변

3

확인. 이것이 제가 사용하던 방식입니다.

의견에서 언급했듯이 Qt 5.x의 경우 컨테이너에 두 개의 함수 QWidget::createWindowContainerQWindow::fromWinId(WId id)을 사용해야합니다. 또한 중요한 것은 함수를 호출 할 때 중요합니다. 다음 구현은 저에게 효과적이며, 다른 것들은 빈 윈도우 또는 중복되고 버그가있는 윈도우를 얻습니다.

컨테이너 앱에 수직 레이아웃이 있다고 가정하면 내 레이아웃이 포함 된 앱을 배치합니다. 컨테이너 MAIN.CPP mainContainer 창에서

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    mainContainer w; 
    char cmd[1000]; 

    QProcess *myProcess1 = new QProcess(); 
    myProcess1->start("utility"); 
    char buff[500]; 
    buff[0]=0; 
    myProcess1->waitForStarted(); 
    myProcess1->waitForReadyRead(); 

    myProcess1->read(buff,100); 
    unsigned long long id1=atoll(buff); 
    fflush(stdout); 
    w.embedApps(id1); 
    myProcess1->write("continue\r\n"); 
    w.show(); 
    a.exec(); 
    myProcess1->kill(); 
    return 0; 
} 

에서

이 하나

void marinaContainer::embedApps(WId id1, WId id2) 
{ 
    QWindow *qw = QWindow::fromWinId(id1); 
    QWidget *w1= QWidget::createWindowContainer(qw,this); 
    ui->verticalLayout->addWidget(w1); 
} 

처럼 마지막으로 유틸리티 응용 프로그램에 embedApps 기능을 추가 할 수 있습니다. MAIN.CPP는

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    utilityMainWindow w; 
    printf("%lld\r\n",w.winId()); 
    fflush(stdout); 
    char trash[100]; 
    //We wait until container was created and say 'ok, coninue' 
    scanf("%99s",trash); 
    w.show(); 
    return a.exec(); 
} 

당신은 부모와 자식 프로세스 사이에 comunicate 수 다른 방법을 사용할 수 있지만이 것은이 데모에 충분하다.

희망이 있습니다. 즐겨.

0

이것은 매우 복잡한 작업이며 완벽한 해결책이 없다는 것을 알고 있습니다. 나는 이미 저기있는 것을 보면서 제안 할 것입니다. 예를 들어 ROS rqt은 대부분이 PyQt을 기반으로하고 있지만 타사 프레임 워크 (즉 - ROS)가 필요하며 실행중인 응용 프로그램의 프로세스 관리와 관련하여 버그가있는 경우에도 이러한 생각을 나타냅니다. 이것은 (지금까지 내가 무엇인가를 찾을 수있는 한) 완전한 해결책이되었습니다.

내가 자동으로 생성했다 (예 roslaunch 또는 rosrun뿐만 아니라 독립 실행 형 응용 프로그램과 같은 ROS를 통해 실행 프로세스의 상태를, 시작을 stoping 및 모니터링을위한) 프로세스 모니터링 도구를 (ROS rqt 사용) 개발 프로젝트에서 일했습니다 또한 설정 파일에서 복원 할 수 있으며 프로세스 상태 복원 기능도 있습니다. 마지막 단계는 백그라운드 프로세스를 실행하거나 응용 프로그램을 일반 위젯으로 변환하고이를 Qt 응용 프로그램에 추가 할 때 상관없이 사용할 수있는 무언가입니다. 기본적으로 "제어 센터"를 시작할 때 가능한 한 프로세스 상태를 복원합니다. PID 파일을 사용하고있는 프로세스에 따라 각각의 추가 정보를 사용했습니다 (모두 자동으로 생성됨).이것은 시작된 외부 프로세스를 자식 프로세스로 실행하지 않고 (즉, 주 앱을 종료하고 다른 모든 프로세스가 종료되는 경우) 메인 애플리케이션이 해당 프로세스 중 시작한 프로세스를 제어 할 수 있도록하려는 경우에 유용합니다. 마지막으로 뛰었습니다. 이 깔끔한 기능을 제외하면 기본적으로 응용 프로그램 유형을 기반으로하는 작은 파생물을 사용하여 공용 인터페이스를 만든 다음 rqt 프레임 워크를 사용하여 해당 인터페이스를 UI에 연결했습니다. 확실히 쉬운 일이 아니 었습니다. 난 당신이 자체 포함 QWidget을 (또는 QObject의 다른 파생) 클래스로 "삽입"원하는 및 다양한 응용 프로그램을 변환하는 것이 제안 쉽게 물건을 만들기 위해

은 일반 Qt를-방법으로 사람들을 포함 (위젯을 부모 QWidget에 추가). 위젯을보다 자연스러운 바탕 화면으로 이동하려면 (클릭, 드래그, 회전도) QGraphicsSceneQGraphicsProxyWidget을 사용할 수 있습니다. 당신은 내가 무슨 말의 느낌을 얻을 수 있도록 스크린 샷 중 하나가이 주제에 대한 내 Here is a reply 아래 재 게시 :

enter image description here

그것은 당신이 찾고되지 정확히 무엇을하지만 당신은 여전히 ​​수 장면의 각 프록시 위젯을 실제로 백그라운드 프로세스를 제어하고 일부 기능을 노출합니다. 당신이 요구하는 것보다 훨씬 쉽습니다. 나는 현재 응용 프로그램이 표시되고 허용되기 때문에이 방법론을 사용하는 이미지 처리 용 응용 프로그램에서 자유 시간에 개인 프로젝트를 수행하고 있습니다 (이 링크는 위에서 언급 한 링크에서 언급 한 것 같습니다). 각 노드는 기본적으로 특정 유형의 위젯이며 시각적으로나 논리적 수준에서 데이터를 생성하는 다른 노드에 연결되는 경우 데이터 흐름을 변경하는 기능을 노드 기반 방식으로 제어합니다.

+0

고마워요 @rdaleksandar 그것은 원하는 솔루션이 아니지만 굉장합니다! – Mquinteiro

관련 문제