[완료] Qt GUI프로그래밍중인데, mainwindow에서 또다른 창(widget)을 열고 싶습니다.
글쓴이: pogusm / 작성시간: 금, 2011/05/06 - 8:18오후
프로그램A(program1.exe) 와 프로그램B(program2.exe)를 만들었는데, 이둘을 합치고 싶습니다.
프로그램A 에 버튼을 추가하여, 해당 버튼을 누르면 프로그램B가 실행되게 하고 싶습니다.
두개의 프로그램(창)은 각각 독립적으로 작동하지만, 프로그램A(부모)를 종료하면 프로그램B(자식)까지 종료되게 하고 싶습니다.
첫번째 방법으로, 프로그램A(program1.exe)에 아래와 같은 코드를 삽입해 보았습니다.
QString program = "./program2.exe"; QStringList arguments; arguments << ""; QProcess *myProcess = new QProcess(this); myProcess->start(program, arguments);
이렇게 하니까 일단 제가 원하던대로 되긴 했는데.. 100% 원하던 바는 아닙니다.
저는 소스코드 수준에서 합쳐서
program1.exe + program2.exe ==> program.exe 와 같이
단일 프로그램으로 만들고 싶습니다.
그래서
두번째 방법으로, 소스를 합친후, mainwindow(프로그램A) 의 버튼슬롯에 프래그램B(Widget)를 여는 코드를 삽입했습니다.
QWidget *w2 = new Widget(); w2->show();
버튼을 누르면 일단 프로그램B가 실행이 되긴 합니다.
하지만, mainwindow(프로그램A)가 실행중에는 widget(프로그램B)이 멈추고, 프로그램A의 작업이 끝난후 프로그램B의 작업이 진행됩니다.
또한, 부모-자식 관계가 아니라서, 프로그램A의 창을 닫아도 프로그램B는 여전히 살아있습니다.
----------
1. QProcess를 이용해서 QWidget *w2 = new Widget(); w2->show(); 을 작동시킬 방법이 있을까요?
2. 아니면, w2를 fork 형태로 실행할 방법이 있을까요?
3. QThread를 이용해서 w2->show();를 해보니까 오류가 나던데, 이같은 경우엔 스레드는 해결책이 될 수 없을까요?
ㅠㅠ
추가 : 테스트용 소스코드 업로드 합니다.
File attachments:
첨부 | 파일 크기 |
---|---|
program1.zip | 6.03 KB |
Forums:
저희는 이런 방법을 사용했는데요
process = new QProcess;
//process->start("cmd.exe", QStringList() << "/C" << "kill_process.bat");
process->start("cmd.exe", QStringList() << "/C" << "c:\\windows\\system32\\taskkill.exe /F /T /IM 실행파일명");
process->start("cmd.exe", QStringList() << "/C" << "c:\\windows\\system32\\taskkill.exe /IM 실행파일명 /F /T");
//s process->waitForFinished(-1);
process->kill();
process->terminate();
해당 프로세스를 종료하는걸 taskkill로 처리했습니다.
질문과는 상관없는 답변으로 보입니다만... ㅇ_ㅇ'''
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
메인윈도우에서 w2->show(); 를 실행하지 말고
메인윈도우에서 w2->show(); 를 실행하지 말고 생성자에 넣으세요.
답변 감사합니다.
근데, 이해를 못하겠습니다 ㅠㅠ
메인윈도우에서 w2->show();를 실행하지 말고,
Widget의 생성장에 무엇을 넣어야 새창(Widget)이 실행될까요?
조금만 더 알려주시면 감사하겠습니다.
GUI 와 프로그램 클라스는 분리하는게
GUI 와 프로그램 클라스는 분리하는게 좋습니다.
프로그램 클라스를 Program2 라 하고,
디자이너에서 Program2 에 사용할 폼을 만들어 Widget2 로 저장한 후,
Widget2 *w2 = new Widget2(); 는 주 프로그램 클라스의 생성자에, 주프로그램 소멸자에는 delete w2 를 넣고
w2->show(); 만 버튼에서 실행하는게 좋을 듯.
아 그렇군요.. 하지만, 제 본 의문에 대한
아 그렇군요..
하지만, 제 본 의문에 대한 해결책은 아닌거 같습니다.
ㅠㅠ
아무튼 감사합니다.
w2 = new Widget() 로 생성된 위젯은
w2 = new Widget() 로 생성된 위젯은 자동으로 독립 프로세스를 갖습니다.
별도로 쓰레딩을 하면 오히려 에러가 나요.
어떠한 형태로 생성하든, 모든 GUI컴포넌트는 같은
어떠한 형태로 생성하든, 모든 GUI컴포넌트는 같은 스레드안에서 돌아갑니다.
다른 스레드로 하면 에러가 나는 것은 독립된 프로세스이기 때문이 아니라 Qt의 GUI는 락없이 하나의 스레드에서 돌아가게끔 설계되어있기 때문입니다.
전에도 말씀드렸지만, 모든 GUI동작은 하나의
전에도 말씀드렸지만, 모든 GUI동작은 하나의 무한루프입니다.
메인에서 계산하면 아무것도 할수 없는 것은, GUI의 루프안에서 계산을 하고 있기때문입니다.
시간이 걸리는 동작을 GUI 스레드에서 실행하면 그 시간동안 모든 이벤트처리가 불가능합니다.
이부분을 별도 스레드로 빼서 처리하면 메인윈도우에서 계산할 때 멈추는 동작은 해결가능합니다.
이것은 위젯이 여러개이기 때문에 생기는 문제가 아닙니다.
메인을 닫으면 자동으로 B도 닫히게 하고 싶다면 B를 생성할때 부모포인터로 메인윈도우를 넘기면됩니다.
다만 일반적으로 위젯이란 것은 부모위젯안에 표시되게되어있습니다.
별도의 창으로 띄우는게 목적이라면 '대화상자(다이얼로그)'라는 것을 이용합니다.
QDialog를 살펴보세요.
누누히 강조하지만 GUI는 단일스레드입니다.
모든 GUI이벤트는 하나의 스레드에서 처리되고, 처리되어야합니다.
스레드를 이용할때, 절대로 GUI스레드에 락을 걸지 마세요.
여기서 스레드로 빼서 처리해야할 것은 시간이 걸리는 메인윈도우의 계산이지, 각 위젯을 서로다른 스레드에서 표시할수는 없습니다.
자세한 답변 감사합니다.
이제야 어느정도 개념이 잡히는 느낌입니다 ㅠㅠ
해결방법을 알아낸건 아니지만..
큰 도움이 되었습니다.
근데 "GUI 쓰레드 락을 걸지 말아라" 라는건
이걸 말하는건가요?
아님 다른 의미인건가요?
네, 맞습니다. Qt로 멀티 스레드 프로그램을 만들때
네, 맞습니다.
Qt로 멀티 스레드 프로그램을 만들때 주의해야할 점으로, GUI스레드와는 비동기방식으로 작동해야합니다.
다른 스레드와 GUI스레드가 데이터를 공유하고 싶을때에는 락을 걸지말고 signal/slot이나 이벤트로 데이터를 주고받아야 합니다.
넵!
친절한 답변 감사합니다.
GUI 자체를 쓰레드로 돌리는 것은
GUI 자체를 쓰레드로 돌리는 것은 엉터리입니다.
버튼을 눌러 시작되는 프로그램을 쓰레드로 돌리세요.
위와 같이 순차적 프로그램에서 프로그램 A 가 진행되고 있는데 다른 프로그램이 돌 리가 없죠.
프로그램 A가 종료될 때 프로그램 B도 종료되게 하려면 당연히 A의 소멸자에서 B를 소멸토록 해야 하며, B의 소멸자는 쓰레드를 끝내는 코드를 포함해야 합니다.
일단 C++ 의 기본부터 먼저 공부하시기 바랍니다.
두개의 Qt쓰레드라고 생각하지 말고 두개의 다른
두개의 Qt쓰레드라고 생각하지 말고
두개의 다른 프로그램이라고 생각하시면 편합니다.
그냥 fork()로 다른 프로세스를 만들어서 and execv()로 실행을 시키세요.
윈도에서 하시는것같은데, QProcess를 적당히 이용해보세요.
아무튼, 프로세스를 새로 fork()하셨다면
자식 프로세스의 PID를 가지고 계실겁니다.
프로그램 A가 종료될때 그 자식 프로세스 (B를 실행시키고 있는)를 죽여버리세요.
간단합니다.
qApp->processEvents() 사용하기
어떠한 이유는 모르겠지만 QT에서 UI가 멈추는 증상이 있다고 합니다.
UI 관련되서 변경되는 시점에 아래 명령어를 추가하는 방식으로 추가해보세요.
qApp->processEvents();
http://stackoverflow.com/questions/12410433/forcing-the-qt-gui-to-update-before-entering-a-separate-function
댓글 달기