GTK,作為與 QT 並存的另外一套圖形庫,深受C 程序員 的喜愛。在同一程序中使用 QT 和 GTK,甚至是其它圖形庫,對於編寫嵌入式(Embeded)程序是十分有意義的。這也正式本文章所闡述的主題。 1. 嵌入式程序的概念 嵌入式程序一般沒有自己的主循環體,它直接使
GTK,作為與 QT 並存的另外一套圖形庫,深受C
程序員的喜愛。在同一程序中使用 QT 和 GTK,甚至是其它圖形庫,對於編寫嵌入式(Embeded)程序是十分有意義的。這也正式本文章所闡述的主題。
1. 嵌入式程序的概念 嵌入式程序一般沒有自己的主循環體,它直接使用窗口的ID來嵌入到其它窗口中。在 Xlib 層次上,使用函數 XReparentWindow 重新設置一個窗口的父窗口:
XReparentWindow(Display *display, Window w,
Window parent, int x, int y)
即可以把窗口 w 嵌入到窗口 parent 中。
嵌入式程序一般使用動態庫載入的方法,這樣使用任何X窗口系統下的圖形庫,都可以通過輸出(Export)其窗口ID的方法和其它程序庫協同工作。嵌入程序需要父窗口來管理窗口的一些操作,如窗口的尺寸管理,鍵盤聚焦等等。一個完整的應用程序也可以嵌入到其它窗口中,一般地,建立主窗口時使窗口不受管理,然後使用XReparentWindow()設置父窗口。
2. 在 QT 中使用 Motif 在 QT 2.x 版本中有一個 QT 的 Xt/Motif 的擴展,它可以使用戶編寫同時支持 Xt/Motif 和 Qt 的程序。QT 對於Xt/Motif 的擴展是建立了類 QXtWidget 和類 QXtApplication,它主要處理了嵌入窗口的底層事件。
建立一個以 QT 為主的包含Motif組件(Widget)的程序,只要使用QXtApplication 建立主程序,設置一個可以包含QT和Motif窗口的主窗口即可,例如:
QXtApplication app(argc, argv, "TwoEditors");
TwoEditors m;
app.setMainWidget(&m);
m.show();
return app.exec();
在 m 中設置兩個窗口,一個是QT類建立的,一個是QXtWidget類建立的,
class TwoEditors : public QMainWindow {
QMultiLineEdit* qtchild;
EncapsulatedXtWidget* xtchild;
public:
TwoEditors() : QMainWindow( 0, "mainWindow") {
QPopupMenu* file = new QPopupMenu( this );
file->insertItem("E&xit", qApp, SLOT( quit() ) );
menuBar()->insertItem( "&File", file );
statusBar();
QSplitter* splitter = new QSplitter( this );
splitter->setOpaqueResize( TRUE );
setCentralWidget( splitter );
xtchild = new EncapsulatedXtWidget( splitter );
qtchild = new QMultiLineEdit( splitter );
qtchild->setText(QTEDMSG);
}
};
3. 在 QT 中使用 GTK 在 QT 中使用 GTK 稍復雜一些,主要是因為必須把 QT 的主循環和 GTK 的主循環融合到一起比較復雜。在軟件包 QGtkWidget 中,作者使用了 GTK 的一部分代碼,QT的一部分代碼和KDE的一部分代碼,構造了 QGtkWidget 類和 QGtkApplication類。
編寫程序的結構和上面的例子類似,
QGtkApplication a( argc, argv );
QMainWindow *wnd=new MainWnd();
QPushButton *Qt=new QPushButton("This is Qt!", wnd);
QGtkWidget *Gtk=new QGtkWidget(wnd);
wnd->resize(200,100);
Qt->setGeometry(0,0,100,50);
Gtk->setGeometry(100,0,100,100);
GtkWidget *box=gtk_
vbox_new(FALSE, 0);
gtk_container_add(GTK_CONTAINER(Gtk->getGtkWidget()), box);
GtkWidget *b=gtk_button_new_with_label("This is GTK!");
gtk_box_pack_start(GTK_BOX(box), b, TRUE, TRUE, 0);
gtk_widget_show(b);
gtk_widget_show(box);
wnd->show();
a.setMainWidget( wnd );
gtk_widget_show(b);
gtk_widget_show(box);
return a.exec();