高手免进!!!
今天下午考完一门科目,终于有时间学习以下gtk了! Devhelp很不错,不但有api手册,还有tutorial和示例源代码,越来越喜欢泡在help里了。。。gtk的界面设计还是很先进的,win上没有的盒子模型和组合表。我早就幻想过能够像设计网页那样方便地设计应用程序的界面,而gtk很容易实现这个想法。创建一个table,你就可以让你的控件以任意形式放置在任意位置的一个或多个单元格中。个人觉得,什么时候能够用一个css文件来给窗体装裱样式就更方便了。
心不在焉的看了1个多小时手册,然后写了1个小时代码(有点笨),结果如下:

配置界面:

源代码:
#include <stdlib.h>
#include <gtk/gtk.h>
#include <time.h>
#include <libnotify/notify.h>
#include <stdio.h>
#define MAX_LINES 1000
#define MAX_CHAR_PER_LINE 100
struct program_data{
int interval;
int display_timeout;
}data = { 60, 5 };
guint timer = 0, ticks = 0;
guint total_lines;
char life_knowledge[MAX_LINES][MAX_CHAR_PER_LINE];
GdkPixbuf *pixbuf;
static int show_notification( const char* title, const char* context )
{
NotifyNotification *n;
n = notify_notification_new (title,
context,
NULL, NULL);
notify_notification_set_timeout (n, data.display_timeout*1000); // 5 seconds
notify_notification_set_icon_from_pixbuf( n, pixbuf );
if (!notify_notification_show (n, NULL))
{
fprintf(stderr, "failed to send notification\n");
return 1;
}
g_object_unref(G_OBJECT(n));
return 0;
}
static void show_helper()
{
int i = rand() % total_lines;
char buf[1000];
int min = ticks / 60;
int hour = min / 60;
if( ticks > 10 ){
sprintf( buf, "\n%s\n\t\n歇一歇吧!您使用电脑已经超过%d小时%d分。", life_knowledge[i], hour, min%60 );
}else{
sprintf( buf, "\n%s\n", life_knowledge[i] );
}
show_notification("健康提示", buf );
}
static void cb_set_interval(GtkWidget* widget, GtkSpinButton* spinner )
{
data.interval = gtk_spin_button_get_value_as_int (spinner);
}
static void cb_set_display_timeout(GtkWidget* widget, GtkSpinButton* spinner )
{
data.display_timeout = gtk_spin_button_get_value_as_int (spinner);
}
static void cb_save_config(GtkWidget* widget, gpointer win)
{
//save config
FILE* fp = fopen("./config", "wb" );
if(fp){
fwrite( &data, sizeof(data), 1, fp );
fclose(fp);
}
gtk_widget_destroy(win);
}
static void show_configuration()
{
GtkWidget *item = NULL;
GtkWidget *win = NULL;
GtkWidget *table = NULL;
GtkAdjustment* adj = NULL;
/* Create the main window */
win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_container_set_border_width (GTK_CONTAINER (win), 8);
gtk_window_set_title (GTK_WINDOW (win), "Life Helper Configuration");
gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER);
table = gtk_table_new( 4, 2, TRUE );
gtk_container_add (GTK_CONTAINER (win), table);
item = gtk_label_new ("Interval (min) ");
gtk_table_attach_defaults (GTK_TABLE (table), item, 0, 1, 0, 1);
adj = (GtkAdjustment*)gtk_adjustment_new (data.interval, 1.0, 60.0*8, 1.0,
10.0, 0.0);
item = gtk_spin_button_new (adj, 0, 0);
gtk_table_attach_defaults( GTK_TABLE(table), item, 1, 2, 0, 1 );
g_signal_connect( item, "value_changed", G_CALLBACK(cb_set_interval), item );
item = gtk_label_new ("Display Timeout (s) ");
gtk_table_attach_defaults (GTK_TABLE (table), item, 0, 1, 1, 2);
adj = (GtkAdjustment*)gtk_adjustment_new (data.display_timeout, 1.0, 15.0, 1.0,
2.0, 0.0);
item = gtk_spin_button_new (adj, 0, 0);
gtk_table_attach_defaults( GTK_TABLE(table), item, 1, 2, 1, 2 );
g_signal_connect( item, "value_changed", G_CALLBACK(cb_set_display_timeout), item );
item = gtk_hseparator_new();
gtk_table_attach_defaults (GTK_TABLE (table), item, 0, 2, 2, 3);
item = gtk_button_new_from_stock (GTK_STOCK_SAVE);
g_signal_connect (item, "clicked", G_CALLBACK(cb_save_config), win);
gtk_table_attach_defaults (GTK_TABLE (table), item, 0, 2, 3, 4);
gtk_widget_show_all (win);
}
void cb_show_helper()
{
show_helper();
}
void cb_configure()
{
show_configuration();
}
void cb_exit()
{
gtk_main_quit();
}
GtkWidget *menu;
void init_menu()
{
menu = gtk_menu_new();
GtkWidget *item;
item = gtk_menu_item_new_with_label("Show Next");
g_signal_connect(G_OBJECT(item), "activate",
G_CALLBACK(cb_show_helper), NULL);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
/* 可爱的分割线 */
item = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
item = gtk_menu_item_new_with_label("Configure");
g_signal_connect(G_OBJECT(item), "activate",
G_CALLBACK(cb_configure), NULL);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
/* 可爱的分割线 */
item = gtk_separator_menu_item_new();
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
item = gtk_image_menu_item_new_from_stock(GTK_STOCK_QUIT, NULL);
g_signal_connect(G_OBJECT(item), "activate",
G_CALLBACK(cb_exit), NULL);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), item);
}
void show_menu(GtkStatusIcon *status_icon, guint button, guint activate_time, gpointer pos)
{
gtk_menu_popup(GTK_MENU(menu),
NULL,
NULL,
NULL,
NULL,
button,
activate_time);
gtk_widget_show_all(GTK_WIDGET(menu));
}
void init_system_tray()
{
GtkStatusIcon* status_icon = gtk_status_icon_new_from_pixbuf(pixbuf);
if(!status_icon){
fprintf(stderr, "failed to load icon file.\n" );
exit( 1 );
}
gtk_status_icon_set_tooltip(status_icon, "生活小助手");
gtk_status_icon_set_visible(status_icon, (gboolean)TRUE);
init_menu();
g_signal_connect(G_OBJECT(status_icon), "popup_menu",
G_CALLBACK(show_menu), status_icon);
}
static gint cb_timer(gpointer d)
{
if( ticks++ % (data.interval*60) == 0 ){
show_helper();
}
return TRUE; //continue
}
static void reload_text()
{
int i;
FILE* fp=fopen("./life.txt", "r");
if(!fp){
fprintf(stderr, "failed to load text life.txt\n");
exit(1);
}
for( i=0; !feof(fp) && i<MAX_LINES; i++ ){
fgets(life_knowledge[i], MAX_CHAR_PER_LINE, fp );
}
total_lines = i;
fclose(fp);
}
int main (int argc, char *argv[])
{
reload_text();
srand(time(NULL));
//load config
FILE* fp = fopen("./config", "rb" );
if(fp){
fread( &data, sizeof(data), 1, fp );
fclose(fp);
}
gtk_init (&argc, &argv);
notify_init("Life Helper");
//Load my Bulb
pixbuf = gdk_pixbuf_new_from_file("bulb.png", NULL );
if(!pixbuf)
{
fprintf(stderr, "failed to load cmcclogin.png\n");
return 1;
}
//Load the system tray
init_system_tray();
//ticks every second
timer = gtk_timeout_add( 1000, (cb_timer), NULL );
gtk_main ();
return 0;
}
这么长的函数名 打的不累啊?
你不觉得像一篇优美的英文文章么。。。
呵呵 同意Xiaoxia的观点!还是这个看起来舒服…
小虾也用代码着色了!
@FB:终于被你发现了!
小虾也用代码着色了!
坏了,虾虾弄到人家也有兴趣了!
代码的字体 用 Fixedsys 是我最喜欢的…………斜体看不清楚
没所谓啦,能看清楚就ok 🙂
不错 关注中
虾哥,怎么编译???
连接的时候要加入libgtk+-2.0以及libnotify库吧
太感谢你了。
刚工作不久,有一个问题两天了没解决,在你这里找到了答案。再次谢谢你!
能帮到你很高兴,谢谢你的支持!