Перейти к содержанию

Исходник простого GUI-окна


Рекомендуемые сообщения

Привет! Никак не могу найти исходник простого GUI-окна под линукс. Подскажите где его взять? Нужно именно простое окно, не консольное и без всяких библиотек, т.е как бы на голом АПИ. Из других прог сложно вырезать кусочек, т.к не знаю что должно в него входить. Помогите пожалуйста, наверняка он есть у многих. Спасибо!

Ссылка на комментарий
Поделиться на другие сайты

#include

#include "demo-common.h"

static GtkWidget *window = NULL;

static void

menuitem_cb (gpointer callback_data,

guint callback_action,

GtkWidget *widget)

{

GtkWidget *dialog;

dialog = gtk_message_dialog_new (GTK_WINDOW (callback_data),

GTK_DIALOG_DESTROY_WITH_PARENT,

GTK_MESSAGE_INFO,

GTK_BUTTONS_CLOSE,

"You selected or toggled the menu item: \"%s\"",

gtk_item_factory_path_from_widget (widget));

/* Close dialog on user response */

g_signal_connect (dialog,

"response",

G_CALLBACK (gtk_widget_destroy),

NULL);

gtk_widget_show (dialog);

}

static GtkItemFactoryEntry menu_items[] =

{

{ "/_File", NULL, 0, 0, "" },

{ "/File/_New", "N", menuitem_cb, 0, "", GTK_STOCK_NEW },

{ "/File/_Open", "O", menuitem_cb, 0, "", GTK_STOCK_OPEN },

{ "/File/_Save", "S", menuitem_cb, 0, "", GTK_STOCK_SAVE },

{ "/File/Save _As...", NULL, menuitem_cb, 0, "", GTK_STOCK_SAVE },

{ "/File/sep1", NULL, menuitem_cb, 0, "" },

{ "/File/_Quit", "Q", menuitem_cb, 0, "", GTK_STOCK_QUIT },

{ "/_Preferences", NULL, 0, 0, "" },

{ "/_Preferences/_Color", NULL, 0, 0, "" },

{ "/_Preferences/Color/_Red", NULL, menuitem_cb, 0, "" },

{ "/_Preferences/Color/_Green", NULL, menuitem_cb, 0, "/Preferences/Color/Red" },

{ "/_Preferences/Color/_Blue", NULL, menuitem_cb, 0, "/Preferences/Color/Red" },

{ "/_Preferences/_Shape", NULL, 0, 0, "" },

{ "/_Preferences/Shape/_Square", NULL, menuitem_cb, 0, "" },

{ "/_Preferences/Shape/_Rectangle", NULL, menuitem_cb, 0, "/Preferences/Shape/Square" },

{ "/_Preferences/Shape/_Oval", NULL, menuitem_cb, 0, "/Preferences/Shape/Rectangle" },

/* If you wanted this to be right justified you would use "", not "".

* Right justified help menu items are generally considered a bad idea now days.

*/

{ "/_Help", NULL, 0, 0, "" },

{ "/Help/_About", NULL, menuitem_cb, 0 },

};

static void

toolbar_cb (GtkWidget *button,

gpointer data)

{

GtkWidget *dialog;

dialog = gtk_message_dialog_new (GTK_WINDOW (data),

GTK_DIALOG_DESTROY_WITH_PARENT,

GTK_MESSAGE_INFO,

GTK_BUTTONS_CLOSE,

"You selected a toolbar button");

/* Close dialog on user response */

g_signal_connect (dialog,

"response",

G_CALLBACK (gtk_widget_destroy),

NULL);

gtk_widget_show (dialog);

}

/* This function registers our custom toolbar icons, so they can be themed.

*

* It's totally optional to do this, you could just manually insert icons

* and have them not be themeable, especially if you never expect people

* to theme your app.

*/

static void

register_stock_icons (void)

{

static gboolean registered = FALSE;

if (!registered)

{

GdkPixbuf *pixbuf;

GtkIconFactory *factory;

char *filename;

static GtkStockItem items[] = {

{ "demo-gtk-logo",

"_GTK!",

0, 0, NULL }

};

registered = TRUE;

/* Register our stock items */

gtk_stock_add (items, G_N_ELEMENTS (items));

/* Add our custom icon factory to the list of defaults */

factory = gtk_icon_factory_new ();

gtk_icon_factory_add_default (factory);

/* demo_find_file() looks in the the current directory first,

* so you can run gtk-demo without installing GTK, then looks

* in the location where the file is installed.

*/

pixbuf = NULL;

filename = demo_find_file ("gtk-logo-rgb.gif", NULL);

if (filename)

{

pixbuf = gdk_pixbuf_new_from_file (filename, NULL);

g_free (filename);

}

/* Register icon to accompany stock item */

if (pixbuf != NULL)

{

GtkIconSet *icon_set;

GdkPixbuf *transparent;

/* The gtk-logo-rgb icon has a white background, make it transparent */

transparent = gdk_pixbuf_add_alpha (pixbuf, TRUE, 0xff, 0xff, 0xff);

icon_set = gtk_icon_set_new_from_pixbuf (transparent);

gtk_icon_factory_add (factory, "demo-gtk-logo", icon_set);

gtk_icon_set_unref (icon_set);

g_object_unref (pixbuf);

g_object_unref (transparent);

}

else

g_warning ("failed to load GTK logo for toolbar");

/* Drop our reference to the factory, GTK will hold a reference. */

g_object_unref (factory);

}

}

static void

update_statusbar (GtkTextBuffer *buffer,

GtkStatusbar *statusbar)

{

gchar *msg;

gint row, col;

gint count;

GtkTextIter iter;

gtk_statusbar_pop (statusbar, 0); /* clear any previous message, underflow is allowed */

count = gtk_text_buffer_get_char_count (buffer);

gtk_text_buffer_get_iter_at_mark (buffer,

&iter,

gtk_text_buffer_get_insert (buffer));

row = gtk_text_iter_get_line (&iter);

col = gtk_text_iter_get_line_offset (&iter);

msg = g_strdup_printf ("Cursor at row %d column %d - %d chars in document",

row, col, count);

gtk_statusbar_push (statusbar, 0, msg);

g_free (msg);

}

static void

mark_set_callback (GtkTextBuffer *buffer,

const GtkTextIter *new_location,

GtkTextMark *mark,

gpointer data)

{

update_statusbar (buffer, GTK_STATUSBAR (data));

}

GtkWidget *

do_appwindow (void)

{

if (!window)

{

GtkWidget *table;

GtkWidget *toolbar;

GtkWidget *statusbar;

GtkWidget *contents;

GtkWidget *sw;

GtkTextBuffer *buffer;

GtkAccelGroup *accel_group;

GtkItemFactory *item_factory;

register_stock_icons ();

/* Create the toplevel window

*/

window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

gtk_window_set_title (GTK_WINDOW (window), "Application Window");

/* NULL window variable when window is closed */

g_signal_connect (window, "destroy",

G_CALLBACK (gtk_widget_destroyed),

&window);

table = gtk_table_new (1, 4, FALSE);

gtk_container_add (GTK_CONTAINER (window), table);

/* Create the menubar

*/

accel_group = gtk_accel_group_new ();

gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);

g_object_unref (accel_group);

item_factory = gtk_item_factory_new (GTK_TYPE_MENU_BAR, "", accel_group);

/* Set up item factory to go away with the window */

g_object_ref (item_factory);

gtk_object_sink (GTK_OBJECT (item_factory));

g_object_set_data_full (G_OBJECT (window),

"",

item_factory,

(GDestroyNotify) g_object_unref);

/* create menu items */

gtk_item_factory_create_items (item_factory, G_N_ELEMENTS (menu_items),

menu_items, window);

gtk_table_attach (GTK_TABLE (table),

gtk_item_factory_get_widget (item_factory, ""),

/* X direction */ /* Y direction */

0, 1, 0, 1,

GTK_EXPAND | GTK_FILL, 0,

0, 0);

/* Create the toolbar

*/

toolbar = gtk_toolbar_new ();

gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),

GTK_STOCK_OPEN,

"This is a demo button with an 'open' icon",

NULL,

G_CALLBACK (toolbar_cb),

window, /* user data for callback */

-1); /* -1 means "append" */

gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),

GTK_STOCK_QUIT,

"This is a demo button with a 'quit' icon",

NULL,

G_CALLBACK (toolbar_cb),

window, /* user data for callback */

-1); /* -1 means "append" */

gtk_toolbar_append_space (GTK_TOOLBAR (toolbar));

gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar),

"demo-gtk-logo",

"This is a demo button with a 'gtk' icon",

NULL,

G_CALLBACK (toolbar_cb),

window, /* user data for callback */

-1); /* -1 means "append" */

gtk_table_attach (GTK_TABLE (table),

toolbar,

/* X direction */ /* Y direction */

0, 1, 1, 2,

GTK_EXPAND | GTK_FILL, 0,

0, 0);

/* Create document

*/

sw = gtk_scrolled_window_new (NULL, NULL);

gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (sw),

GTK_POLICY_AUTOMATIC,

GTK_POLICY_AUTOMATIC);

gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (sw),

GTK_SHADOW_IN);

gtk_table_attach (GTK_TABLE (table),

sw,

/* X direction */ /* Y direction */

0, 1, 2, 3,

GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,

0, 0);

gtk_window_set_default_size (GTK_WINDOW (window),

200, 200);

contents = gtk_text_view_new ();

gtk_container_add (GTK_CONTAINER (sw),

contents);

/* Create statusbar */

statusbar = gtk_statusbar_new ();

gtk_table_attach (GTK_TABLE (table),

statusbar,

/* X direction */ /* Y direction */

0, 1, 3, 4,

GTK_EXPAND | GTK_FILL, 0,

0, 0);

/* Show text widget info in the statusbar */

buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (contents));

g_signal_connect_object (buffer,

"changed",

G_CALLBACK (update_statusbar),

statusbar,

0);

g_signal_connect_object (buffer,

"mark_set", /* cursor moved */

G_CALLBACK (mark_set_callback),

statusbar,

0);

update_statusbar (buffer, GTK_STATUSBAR (statusbar));

}

if (!GTK_WIDGET_VISIBLE (window))

{

gtk_widget_show_all (window);

}

else

{

gtk_widget_destroy (window);

window = NULL;

}

return window;

}

Ссылка на комментарий
Поделиться на другие сайты

Вопросы:

1. GTK - это надстройка над голом АПИ? Просто надо найти на низком уровне, типа как в винде - CreateWindow(), функция окна и т.д.

2. Где найти "demo-common.h"?

3. Как правильно откомпилировать? Я делал gcc window.cpp (исходник сохранил в window.cpp), но получил кучу ошибок.

Ссылка на комментарий
Поделиться на другие сайты

Gtk+ (см. Gnome) - одна из надстроек над сервером X. Если хочешь писать на голом API, ищи исходники по XLib (кстати, их очень немного). Но я использую не Gtk+ (хотя и под него раньше писал), а QT (см. KDE). В нем ГОРАЗДО удобнее и красивее - и интерфейс приятней и полностью объектно-ориентированная среда. А X API своими безумными структурами напоминает WinAPI, где чтобы создать простое окно, нужно понаписать до фига ненужного кода. В QT все удобнее: создать любой Widget (т.е. любой ui-контрол от кнопки до просмотрщика HTML) можно как простой объект класса со стандартными установками; если нужны другие значения его св-в, они либо передаются прямо в конструкторе, либо меняются простейшими вызовами ф-ий. А главное - ничего лишнего, хотя возможности больше, чем на MFC, WinAPI или Gtk+.

Короче, я двумя руками за KDE/QT. Не надо орать на меня про их лицензии и т.п., я здесь говорил только об удобстве программирования.

Ссылка на комментарий
Поделиться на другие сайты

Спасибо за инфу! Но мне как раз и нужно X API, которое напоминает WinAPI, т.е. то, где нужно писать много ненужного кода. Я это и имел в виду с самого начала, вот только никак найти его не могу. Нужно вообще самое простое элементарное окно. Помогите пожалуйста!

Ссылка на комментарий
Поделиться на другие сайты

/*

См. книжку XLib Programming Manual (Christophe Tronche). По идее, должна лежать на http://www.lsv.ens-cachan.fr/~tronche/xlib-manual.tar.gz Книжка хороша как справочник, там описана куча функций, только как хелп ее использовать я бы не стал. Я потратил около (не пугайся) 3 часов, чтобы сваять этот исходник по этой книжке, но больше ничего посоветовать не могу - особо иксами не заморачивался. Читай ман.

Если чего еще найдешь, я буду ОЧЕНЬ признателен, если ты вышлешь это мне. Удачи!

Игорь.

*/

// Комменты на случай, если форум сотрет все в треугольных скобках

#include // X11/Xlib.h

#include // X11/Xatom.h

#include // iostream.h

#include // stdlib.h

int main(int argc, char *argv[])

{

Display *display = XOpenDisplay(NULL);

unsigned long mask=0;

XSetWindowAttributes attributes;

attributes.background_pixmap = None;

attributes.background_pixel = WhitePixel(display,DefaultScreen(display));

mask |= CWBackPixel;

attributes.border_pixmap = XA_RGB_DEFAULT_MAP;

attributes.border_pixel = 0;

attributes.bit_gravity = ForgetGravity;

attributes.win_gravity = NorthWestGravity;

attributes.backing_store = NotUseful;

attributes.backing_planes = 1;

attributes.backing_pixel = 0;

attributes.save_under = false;

attributes.event_mask = ButtonPressMask | ButtonReleaseMask | KeyPressMask | ExposureMask | StructureNotifyMask; // На самом деле, здесь половина тебе не нужна

attributes.do_not_propagate_mask = 0;

attributes.override_redirect = false;

attributes.colormap = XA_RGB_DEFAULT_MAP;

attributes.cursor = None;

Window w = XCreateWindow(display,DefaultRootWindow(display),0,0,800,600,1/* border */,DefaultDepth(display,DefaultScreen(display))/* depth */,CopyFromParent/* class */,CopyFromParent/* visual */,mask/* valuemask */,&attributes);

Atom wm_protocols = XInternAtom(display,"WM_PROTOCOLS",false);

Atom wm_delete_window = XInternAtom(display,"WM_DELETE_WINDOW",false);

XSetWMProtocols(display,w,&wm_delete_window,1);

switch (w)

{

case BadWindow:

cout<<"Error creating window (BadWindow)!"<

break;

case BadAlloc:

cout<<"Error creating window (BadAlloc)!"<

break;

case BadColor:

cout<<"Error creating window (BadColor)!"<

break;

case BadCursor:

cout<<"Error creating window (BadCursor)!"<

break;

case BadMatch:

cout<<"Error creating window (BadMatch)!"<

break;

case BadPixmap:

cout<<"Error creating window (BadPixmap)!"<

break;

case BadValue:

cout<<"Error creating window (BadValue)!"<

break;

default:

cout<<"Window created. Id: "<

break;

}

XRaiseWindow(display,w);

XMapWindow(display,w);

XEvent event;

while (true)

{

XNextEvent(display,(XEvent*)&event);

switch (event.type)

{

case ClientMessage:

if (event.xclient.message_type == wm_protocols && event.xclient.data.l[0] == (signed)wm_delete_window)

{

XCloseDisplay(display);

exit(0);

}

break;

}

}

return EXIT_SUCCESS;

}

Ссылка на комментарий
Поделиться на другие сайты

Спасибо EL за инфу, но у меня к тебе еще есть вопросы. Поскольку в линуксе я новенький, то у меня возникли проблемы с компиляцией этого исходника Sad( Раньше я пробовал компилировать файлы так:

gcc AnyFile.cc

и в текущей директории появляется исполняемый файл, который можно запустить. В этот раз по аналогии делал также:

gcc SourceGuiWindow.cc

но файл не появился. К тому же получил кучу сообщений, типа undefined reference to `XOpenDisplay' и т.д. Подскажи пожалуйста, как мне довести это дело до конца, т.е. откомпилировать и увидеть то самое долгожданное элементарное окно.

Спасибо, что потратил на это время!

Ссылка на комментарий
Поделиться на другие сайты

Компилируй с параметром -lX11

Кроме того, может потребоваться явно указать каталог, в котором лежат иксовые библиотеки. Т.к. на моей системе это /usr/X11R6/lib, то можно выполнить такую команду:

gcc -L/usr/X11R6/lib -lX11 ./что_компилировать.cpp -o куда_писать_результат

Попробуй. Если не сработает - я проверю, скажу точно - просто я сейчас не дома на Linux-системе, слету проверить не могу.

Ссылка на комментарий
Поделиться на другие сайты

В каталоге /usr/X11R6/lib у меня тоже лежат какие-то библиотеки.

Я компилировал так как ты сказал: gcc -L/usr/X11R6/lib -lX11 ./api.cpp -o /home/neo/doc/output.

Опять куча ошибок. Вот как они начинаются (наверно форум не так отобразит):

In file included from /usr/include/c++/3.3.1/backward/iostream.h:31,

from api.cpp:3:

/usr/include/c++/3.3.1/backward/backward_warning.h:32:2: warning: #warning This file includes at least one deprecated or antiquated header. Please consider using one of the 32 headers found in section 17.4.1.2 of the C++ standard. Examples include substituting the header for the header for C++ includes, or instead of the deprecated header . To disable this warning use -Wno-deprecated.

/root/tmp/ccIlZZgE.o(.text+0x184): In function `main':

: undefined reference to `std::basic_ostream >& std::endl >(std::basic_ostream >&)'

/root/tmp/ccIlZZgE.o(.text+0x191): In function `main':

: undefined reference to `std::cout'

/root/tmp/ccIlZZgE.o(.text+0x196): In function `main':

: undefined reference to `std::basic_ostream >& std::operator<< >(std::basic_ostream >&, char const*)'

/root/tmp/ccIlZZgE.o(.text+0x19f): In function `main':

: undefined reference to `std::basic_ostream >::operator<<(std::basic_ostream >& (*)(std::basic_ostream >&))'

/root/tmp/ccIlZZgE.o(.text+0x1af): In function `main':

Ссылка на комментарий
Поделиться на другие сайты

Оказывается как всегда проще некуда. Сам не знаю почему я раньше его не нашел, думаю потому что, не знал того, что "голый" API в линуксе называется Xlib. В любом случае всем большое спасибо!!!

#include

#include

main()

{

// Open a display.

Display *d = XOpenDisplay(0);

if ( d )

{

// Create the window

Window w = XCreateWindow(d, DefaultRootWindow(d), 0, 0, 200,

100, 0, CopyFromParent, CopyFromParent,

CopyFromParent, 0, 0);

// Show the window

XMapWindow(d, w);

XFlush(d);

// Sleep long enough to see the window.

sleep(10);

}

return 0;

}

You can compile the program with the following command:

prompt$ g++ test.cpp -L/usr/X11R6/lib -lX11

prompt$ ./a.out

Ссылка на комментарий
Поделиться на другие сайты

  • 3 месяца спустя...

Там вся куча ошибок из-за iostream

#include // <iostream.h>

а на современном С++ (я сам только месяц назад просветился)

#include // <iostream>

using namespace std;

так теперь правильно поключаются все эти std::...

Ссылка на комментарий
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

Загрузка...
×
×
  • Создать...