gpt4 book ai didi

c - 是否有任何以类似于在 C 中使用 GTK 的小部件的方式打开/查看/与另一个程序交互?

转载 作者:太空宇宙 更新时间:2023-11-04 04:28:38 24 4
gpt4 key购买 nike

因此,在 Linux 中,我试图让一个基于 GTK 的程序打开另一个程序,但我不想在它自己的窗口中打开它,而是想将它放在第一个程序内笔记本的新页面中。我不知道从哪里开始。有没有人以前做过这样的事情,或者有什么建议?

*编辑/更新(2017 年 1 月 14 日):不久前,我刚刚回过头来搞乱代码,遇到了障碍。让我先这样说:当我开始做这件事时,我知道 c 的绝对基础知识。我可以毫无困难地编写一个奇特的 hello world,但仅此而已。我用谷歌搜索到了这一点,但我不知道自己到底在做什么。我要提前为过于冗长的评论和木头主题道歉,这是为了帮助我清楚地了解我认为它是如何工作的,并分别在内部笑话中。

我现在已经停止尝试从 gtk 程序中打开程序。无论如何,这段代码的想法是它应该监视在桌面上打开的窗口,获取它们的 id,并使用它来将所述窗口放入 gtk 套接字,然后将其放入笔记本的新选项卡中。我宁愿能够在任何使用 X 的现有 Linux 桌面环境上运行它,而不是尝试重写任何 DE 组件。除了这个以外,我也无法修改在桌面上打开窗口的程序的代码。如果有人能告诉我为什么这段代码不起作用,那将非常有帮助。我也很乐意接受人们想要提供的任何编码指导。正如我所说,我是新手。

我用这个编译它(这里的撇号实际上应该是反引号,所以不要只是复制粘贴这个!):
gcc 'pkg-config --cflags gtk+-3.0' -o LogTest logtest.c -lX11 'pkg-config --libs gtk+-3.0 gtk+-x11-3.0 gmodule-2.0'

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <math.h>
#include <ctype.h>
#include <gtk/gtk.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <gdk/gdk.h>
#include <gdk/gdkx.h>
#include <gtk/gtkx.h>
#include <X11/Xlibint.h>
#include <X11/Xutil.h>
#include <X11/Xresource.h>

#define WOOD "Lumber"

int plywood(int argc, char **argv, int pipe[2])//Not sure what the variables are for, but they are referenced by the gtk initialiser.
{

close (pipe[1]);//Close the input pipe, sinse we won't be using it.


//Variables, remember "GtkWidget" acts like a variable type.
GtkWidget *window_main;//Main window, holds everything.
GtkWidget *box_main;//Main box, seperates/holds the main notebook.
GtkWidget *notebook_main;//Main notebook for main things.
GtkWidget *label_running;//Label for the running notebook.
GtkWidget *label_open;//
GtkWidget *notebook_running;//Notebook for running programs.
GtkWidget *box_running;//Box for containing the running notebook within a tab in the main notebook.
GtkWidget *ev_box_socket;//This acts to help glue the socket to the box.
Window xid;//Holds the window id for the program comming from woodglue that we are putting into the running notebook (after some finagling).
Window check = 0;//Holds the last window id makes sure we are not doing the same thing twice.
GtkWidget *socket;//This is the thing we stuff the external window into.
GtkWidget *box_socket;//This holds the socket for input into the other box, to goin the notebook.
Window plywood = 0;//holds the window id for plywood. it should be the first one to come in.
GtkWidget *box_placeholder;//This box is a place holder.
int ftc = 0;//This helps to record what run of the loop we are on.
double test;

//Start GTK
gtk_init(&argc, &argv);//Sets the groundwork for all of the gtk funtions and such.


//Making Labels
label_running = gtk_label_new("Open Windows");//Creats a label with the text "Open Windows".

gtk_widget_set_hexpand(GTK_WIDGET(label_running), TRUE);//Tells the label to expand in thehorizontal direction if it can.

label_open = gtk_label_new("test");//Creats a label with the text "test".

gtk_widget_set_hexpand(GTK_WIDGET(label_open), TRUE);//


//running programs box
box_running = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);//Makes a new box, puts it in the variable.


//Active Programs notebook
notebook_running = gtk_notebook_new();//Creates a new notebook and puts it into the variable.

box_placeholder = gtk_button_box_new(GTK_ORIENTATION_VERTICAL);

gtk_notebook_insert_page(GTK_NOTEBOOK(notebook_running), GTK_WIDGET(box_placeholder), GTK_WIDGET(label_open), 0);//Inserts a placeholder tab into the running notebook.

gtk_notebook_set_tab_pos(GTK_NOTEBOOK(notebook_running), GTK_POS_BOTTOM);//Tells the running notebook to put its tabs on the bottom.



//Main Notebook
notebook_main = gtk_notebook_new();//Makes a new notebook, the thing with the tabs, and places it in "notebook_main".

gtk_notebook_insert_page(GTK_NOTEBOOK(notebook_main), GTK_WIDGET(box_running), GTK_WIDGET(label_running), 0);//Puts the running box into the main notebook and names the tab with the running label. Places it withid 0.


//Main Box
box_main = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);//Creates and puts a new horizontal box into the "box_main" variable with "0" pixles spacing its contents.


//Building the darn window
window_main = gtk_window_new(GTK_WINDOW_TOPLEVEL);//Creates and places the main window,"wood_GUI" into the variable "window_main".

gtk_window_set_title(GTK_WINDOW(window_main), WOOD);//Names window_main after the latest version, defined by "WOOD".

gtk_window_set_default_size(GTK_WINDOW(window_main), 800, 480);//Window size in pixles (object, width, hight).

gtk_container_set_border_width(GTK_CONTAINER(window_main), 0);//Sets the border width of "window_main" to "0", making it as small as possible.

gtk_window_set_position(GTK_WINDOW(window_main), GTK_WIN_POS_CENTER_ALWAYS);//Tells the "window_main" to always apear in the center of the screen.


//Packing
gtk_box_pack_start(GTK_BOX(box_running), GTK_WIDGET(notebook_running), TRUE, TRUE, 0);//Puts the running notebook into the running box lest it expand and tells it to fill the space. Also places it in the first slot.

gtk_box_pack_start(GTK_BOX(box_main), GTK_WIDGET(notebook_main), TRUE, TRUE, 0);//In order, this selects "box_main" and places "nootebook_main" within it, left to right or top to bottom, depending on box orientation; it then sets its ability to expand if given extra space to "TRUE" and its directive to fill the space it is givin to "TRUE"; Finnally, it sets the spacing between sections in the box to "0".

gtk_container_add(GTK_CONTAINER(window_main), box_main);//Adds "box_main" to the "window_main" container.


//Connect signals
g_signal_connect(window_main, "delete_event", G_CALLBACK(gtk_main_quit), NULL);//This makes sure the program closes when the window is closed. No idea how it works.


//Show what we made.
gtk_widget_show_all(window_main);//Shows the window. All widgets within shown by default.


printf("\n\nAbout to start GTK loop.\n\n");

//Loop
for(;;)//Forever...
{

//gtk_main_iteration_do(0);//Handle the next gtk event.

read(pipe[0], &xid, sizeof(xid));//Read the window id into xid from the pipe.

//printf("\n\nAbout to run GTK loop.\n\n");


if(xid != 0 && xid != check && xid != plywood)//If the xid is not 0, and not the same as the last one, and not the plywood window...
{
test = xid;


printf("\n\nRead a valid id, it was %lf.\n\n", test);

if(ftc != 0)//If this is not the first run...
{
socket = gtk_socket_new();//Creates a new socket.

ev_box_socket = gtk_event_box_new();//Creates a new event box for the socket.

box_socket = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);//creates a new box for the event box.

gtk_container_add(GTK_CONTAINER(ev_box_socket), socket);//Puts the socket into the socket event box.

gtk_container_add(GTK_CONTAINER(box_socket), ev_box_socket);//Puts the socket event box into the socket box.

gtk_box_pack_start(GTK_BOX(box_socket), GTK_WIDGET(ev_box_socket), TRUE, TRUE, 0);

gtk_notebook_insert_page(GTK_NOTEBOOK(notebook_running), GTK_WIDGET(box_socket), GTK_WIDGET(label_open), 1);//Adds a pag with the prepared socket box and socket.

gtk_socket_add_id(GTK_SOCKET(socket), xid);//Places the id into the socket.

check = xid;//Sets thecheck to the previous id.

gtk_widget_show_all(notebook_running);//Shows everything in the running notebook.
}

else if(ftc == 0)//If this is the first run...
{
plywood = xid;//Sets the first window id recived as our window id.

ftc = 1;//Sets second run.

printf("\n\nJust had first run of valid ID.\n\n");

}

else if(ftc == 1)//If this is the second run...
{
gtk_notebook_remove_page(GTK_NOTEBOOK(notebook_running), 0);//Remove the placeholder page in the running notebook.

ftc = 2;//Set third+ run.

printf("\n\nJust had second run of valid ID.\n\n");
}

printf("\n\nFinnished a run of valid ID.\n\n");
}




gtk_main_iteration_do(0);
}

printf("\n\nOut of the GTK loop, don't know how that happened.\n\n");

//gtk_main();//This is the basic premade GTK loop.


return 0;//Ends the main function.
}

//woodglue function
int woodglue(int argc, char **argv, int pipe[2])//This checks for events that relate to windows being created on the desktop.
{

close (pipe[0]);//Close the input pipe since we won't be using it here.


//Variables
Display *dpy;//This will hold the default display identifier, neccisary for almost all x functions.
Window root;//Declares a window variable called root for holding the window id of the root window.
Window xid;//This will hold thewindow id for the windows that have mapped themselves to the display withen the root window.
XEvent ev;//This is a structure for holding event passed to us by the X server.
double test = 0;
/*
For referance of the XEvent structure, some of its components are also structures. (Do not uncoment.) :

typedef union _XEvent {
int type; // must not be changed
XAnyEvent xany;
XKeyEvent xkey;
XButtonEvent xbutton;
XMotionEvent xmotion;
XCrossingEvent xcrossing;
XFocusChangeEvent xfocus;
XExposeEvent xexpose;
XGraphicsExposeEvent xgraphicsexpose;
XNoExposeEvent xnoexpose;
XVisibilityEvent xvisibility;
XCreateWindoEvent xcreatewindow;
XDestroyWindowEvent xdestroywindow;
XUnmapEvent xunmap;
XMapEvent xmap;
XMapRequestEvent xmaprequest;
XReparentEvent xreparent;
XConfigureEvent xconfigure;
XGravityEvent xgravity;
XResizeRequestEvent xresizerequest;
XConfigureRequestEvent xconfigurerequest;
XCirculateEvent xcirculate;
XCirculateRequestEvent xcirculaterequest;
XPropertyEvent xproperty;
XSelectionClearEvent xselectionclear;
XSelectionRequestEvent xselectionrequest;
XSelectionEvent xselection;
XColormapEvent xcolormap;
XClientMessageEvent xclient;
XMappingEvent xmapping;
XErrorEvent xerror;
XKeymapEvent xkeymap;
long pad[24];
}XEvent;
*/



if(!(dpy = XOpenDisplay(0x0)))//If the display does not return,
{
printf("\n\nX couldn't connect to the display.\n\n");

return 1;//return error.
}

root = DefaultRootWindow(dpy);//Collects the id of the default root window.

XSelectInput(dpy, root, SubstructureNotifyMask);//Tells the root window that we want to get events that relate to changes in the substructure.

printf("\n\nX connected to the display.\n\n");

for(;;)//Forever,
{

XNextEvent(dpy, &ev);//This throws the next event in the que int the "ev" structure thing.

printf("\n\nThe x loop just ran.\n\n");

if(ev.type == MapNotify)// && ev.xcreatewindow.parent == root)//If the event type is a notification of a window being mapped to the root window, and its parent is the root (as of right now, I am not sure that all the windows we are looking for have root as the parent, so that is disabled),
{
printf("\n\nJust got a map notify event.\n\n");

xid = ev.xcreatewindow.window;//place the window id of the created window into "xid".

write(pipe[1], &xid, sizeof(xid));//write the id, however long it is, into the input stream, sending it to plywood. Unknown if this pauses the loop.

test = xid;

printf("\n\nJust sent the window id, it was %lf\n\n", test);

xid = 0;
}


}//And then we loop to check the next event.

return 0;//I assume we need this, but maybe not for X...
}




//Main Function
int main (int argc, char **argv)//Forks the program and sets up the i/o stream.
{

pid_t pid;//This variable serves to identify the program during a fork, a value of 0 represents the child proccess, where 1 is the parent.

int pipe[2];//This initializes the file stream for use between the two versions of the program.

pid = fork();//Forks the program, creating an additional iteration with pid = 0

if(pid == (pid_t) 0)//If this is the child proccess,
{
printf("\n\nChild started.\n\n");

plywood(argc, argv, pipe);//launch the plywood function, passing the starting varibles as well as the file stream "pipe".
}

else if(pid == (pid_t) 1)//Else for the parent proccess,
{
printf("\n\nParent Started.\n\n");

woodglue(argc, argv, pipe);//launch the woodglue function, passing the starting varibles as well as the file stream "pipe".
}

else
{

}

return 0;

}

最佳答案

查看 GtkPlug and GtkSocket widgets ,但要注意它们会阻止您的程序跨平台移植。大多数窗口系统不支持这个;只有 X 可以。

关于c - 是否有任何以类似于在 C 中使用 GTK 的小部件的方式打开/查看/与另一个程序交互?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38809392/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com