نمایش نتایج 1 تا 9 از 9

نام تاپیک: اموزش برنامه نویسی با gtk

  1. #1

    اموزش برنامه نویسی با gtk

    کار رو با یک مثال ساده شروع می کنم در این مثال مطالبی مطرح میشه که در بیشتر برنامه ها یی که بعدا می نویسیم استفاده می شه
    مثال اول
    #include <gtk/gtk.h>
    int main(int argc , char *argv[] ) {
    GtkWidget *window ;
    gtk_init( &argc , &argv);
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_show(window);
    gtk_main();
    Return 0;
    }


    خط اول : همه برنامه هایی که از gtk استفاده می کنند شامل این خط می شوند که این سرفایل شامل تعریف متغییر ها توابع و ساختار ها و غیره می شه و باید در برنامه های خود انرا بگنجانیم .
    خط چهارم : در این خط ما تابع gtk_init را فراخوانی کردیم که این خط هم در تمام برنامه ها استفاده می شه و برخی چیزها رو برای ما تنظیم می کنه مثل مقدار پایه و رنگ که نتیجه فراخوانی این تابع است و بطور کلی این کتابخانه رو بصورت خودکار برای ما مقداردهی اولیه می کنه.
    خط پنجم و ششم : در این خطوط ما یک پنجره برای برنامه خود ایجاد کردیم که درصورتی که ما سایز انرا مشخص نکنیم بصورت پیش فرض 200 در 200 در نظر گرفته می شود زیاد نگران نحوه ایجادش و کدهاش نباشید به زودی همه انها را خواهید اموخت.
    خط ششم : می گوید که ما widget خود را تنظیم کردیم و ویژگی های لازم را تنظیم کردیم و حال می خواهیم که انرا برای ما نشان دهد (widget یک شی هست مثلا یک دکمه یا یک تکست باکس)
    خط هفتم : تابع gtk_main را فراخوانی می کنیم که ان نیز در تمام برنامه هایی که از gtk استفاده می کنیم باید در کد های ما قرار داشته باشه . وقتی برنامه به این نقطه می رسد gtk به حالت خواب میره و منتظر رویداد x می شه ( مثل کلیک موس یا فشار یک دکمه ) در واقع یک حلقه رو ایجاد می کنه که مدام اجرا میشه تا اینکه یک رویداد اتفاق بیفته و در برابر ان عکس العمل انجام بده .
    انچه که از این مثال فهمیدیم
    قالب کلی یک برنامه که از gtk استفاده می کند در اکثر موارد به شکل زیر می باشد
    #include <gtk/gtk.h>
    int main(int argc, char &argv[]){
    gtk_init(&argc,&argv);

    gtk_main();
    return 0;
    }

    برای کامپایل برنامه در لینوکس می تونید از دستور زیر استفاده کنید
    g++ `pkg-config --cflags --libs gtk+-2.0` -o name.cpp nameout
    که بجای name.cpp مسیر جایی رو که در انجا برنامه رو ذخیره کردید می دید و nameout هم نامی هست که می خواهید برنامه کامپایل شده داشته باشه.
    اگه تو ویندوز کد می نویسید می تونید دستوراتی که تو مقاله ای که تو سایت نوشتم بخونید
    مقاله نحوه نصب gtk در ویندوز و پیکربندی ان برای کامپایل برنامه ها با ویژوال سی پلاس پلاس

    اگه همه کار ها رو درست انجام داده باشید باید زمانی که برنامه خود را اجرا می کنید مثل شکل پایین باشه

  2. #2
    مثال دوم
    در مثال قبل شما ساختار کلی یک برنامه رو که از gtk استفاده می کرد دیدید در این مثال من می خوام نحوه ایجاد یک widget رو به شما اموزش بدم
    Widget چیه گفتم که منظور از widget یک شی هست و gtk در واقع کتابخانه ای که شامل یک سری widget ها مثل label یا button و ... هست که ما از اونها استفاده می کنیم برای ایجاد یک رابط گرافیکی و اما مثال
    #include <gtk/gtk.h>
    int main(int argc , char *argv[]){
    gtk_init(&argc,&argv);
    GtkWidget *window;
    GtkWidget *button;
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    button=gtk_button_new();
    gtk_container_add(GTK_CONTAINER(window),button);
    gtk_widget_show(window);
    gtk_widget_show(button);
    gtk_main();
    return 0;
    }


    با اجرای این برنامه شما یک پنجره و دکمه که در اون وجود داره رو می بینید

    حال توضیح کد بالا : برخی از قسمت ها باید برای شما اشنا باشه چون اونها رو در مثال اول هم بکار بردیم و گفتیم که توابعی مثل gtk_init و gtk_main توابعی هستن که در تمام برنامه ها باید وجود داشته باشند حال توضیح قسمت های دیگر کد
    ما برای ایجاد هر یکwidget ( در مثال بالا یک دکمه ) سه خط کد باید به برنامه خود اضافه کنیم ان سه خط اینها هستن
    GtkWidget * name ;
    name=gtk_namebase_new();
    gtk_widget_show(name);

    این سه خط رو ما در اکثر موارد برای ایجاد widget دلخواه خود به کد هامون اضافه می کنیم
    در خط اول ما یک اشاره گر از نوع gtk تعریف می کنیم که name در واقع نام اون اشاره گر هست در خط دوم ما برای اشاره گر خود تخصیص حافظه می کنیم و با استفاده از تابعی که در بالا اشاره شد اون widget که می خواهیم می سازیم در خط بعدش هم می گیم اون widget که ساختیم به ما نشون بده همین!! در کد بالا namebase اون نوع widget هست که می خواهیم بسازیم البته در مورد تابع gtk_namebase_new() باید گفت که این تابع یک الگوی عام هست و برای برخی widget ها کمی شکلش فرق می کنه که برای اطلاعات بیشتر می تونید به راهنمای کتابخانه مراجعه کنید یا اینکه صبر کنید تا من در پست های بعدی بگم خوب برای دست گرمی ما برای ایجاد یک label از کدهای زیر استفاده می کنیم
    GtkWidget * Label1 ;
    Label1=gtk_label_new();
    gtk_widget_show(Label1);

    بر طبق مطالبی که در بالا ذکر کردم ما در مثال دوم 2 widget ساختیم یکی پنجره و یک دکمه که کدهاشون این بود
    GtkWidget  *button;
    button=gtk_button_new();
    gtk_widget_show(button);

    اگه بخوایم بر روی دکمه ای که ایجاد می کنیم مطلبی نوشته باشد می تونیم از تابع gtk_button_new_with_label(“string”) استفاده کنیم که بر این اساس کد های بالا بدین شکل میشه
    GtkWidget  *button;
    button=gtk_button_new_with_label(“Welcome”);
    gtk_widget_show(button);

    که یک دکمه ایجاد میکنه که روی ان عبارت Welcome نوشته شده . نگران این توابع نباشید من تک تک این widget ها رو با ویژگی ها و توابع انها بیان خواهم کرد من فقط می خوام شما شکل کلی کدها رو یاد بگیرید اینطوری کار راحت تر میشه .
    خوب widget دیگر ما یک پنجره بود
    GtkWidget  *window;
    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_show(window);

    که کد های بالا برای ایجاد اون بود در مورد پارامتر تابع gtk_window_new() باید بگم که تنها دو مقدار براش وجود داره عبارت GTK_WINDOW_TOPLEVEL برای ایجاد یک پنجره ساده و عبارت GTK_WINDOW_POPUP برای ایجاد یک پنجره پاپاپ .
    خوب از توابع دیگه ای که برای تنظیم پنجره بکار میره می شه به توابع زیر اشاره کرد
    gtk_window_set_title(GTK_WINDOW(name),”string”  );

    که برای تنظیم عنوان پنجره استفاده می شه و name نام اشاره گری هست که به پنجره اشاره می کنه و string هم عنوان پنجره میشه مثلا برای مثال دو میشه این
    gtk_window_set_title(GTK_WINDOW(window),”Welcome  ”);

    و با استفاده از تابع زیر هم می تونید خاصیت resize پنجره رو فعال یا غیر فعال کنید
    gtk_window_set_resizable(GTK_WINDOW(name),Boolean)  ;

    که مثلا اگه بخوایم در پنجره مثال دوم ما خاصیت resize غیر فعال بشه کد ما میشه این
    gtk_window_set_resizable(GTK_WINDOW(window),FALSE)  ;

    برای تعیین اندازه پنجره هم می تونید از تابع زیر استفاده کنید
    gtk_widget_set_size_request(GTK_WIDGET(name),width  ,hight);

    خوب برگردیم به مثال دوم در اونجا یه خط کد هست که هنوز توضیح ندادم
    gtk_container_add(GTK_CONTAINER(window),button);

    خوب با استفاده از این تابع به gtk می گیم که دکمه ما رو در درون پنجره قرار بده . این تابع تنها می تونه یک widget رو در پنجره قرار بده و اگه شما دوتا دکمه داشته باشید این تابع دیگه جواب گو نیست و باید از روشی به نام بسته بندی کردن widget استفاده کنیم که در پست بعدی به بیان اون می پردازم .

  3. #3
    وقتی که ما یک برنامه کاربردی ایجاد می کنیم عمدتا بیش از یک widget رو در پنجره خود قرار می دیم .ما در مثال دوم یک دکمه رو در پنجره خود قرار دادیم که این کار رو با استفاده از تابع gtk_container_add() انجام دادیم که کار این تابع این هست که یک widget رو برای ما در پنجره قرار بده ولی حال اگه بخوایم بیش از یک widget رو در پنجره قرار بدیم باید چکار کنیم ؟ برای این کار ما از روش بسته بندی widget ها استفاده می کنیم . بسته بندی widget ها رو به دو طریق میشه انجام داد استفاده از جدول یا استفاده از جعبه .
    که در این پست روش بسته بندی با استفاده از جدول رو اموزش می دم و روش بسته بندی با استفاده از جعبه ها رو در پست اینده اموزش می دم .
    بسته بندی با استفاده از جدول ها
    برای استفاده از این روش ابتدا ما یک جدول ایجاد می کنیم بعد هر یک از widget ها رو در خانه های اون قرار می دیم . برای رسم یک جدول از تابع زیر استفاده می کنیم
    gtk_table_new(rows , columns , Boolean);

    که پارامتر اول تعداد سطر های جدول پارامتر دوم تعداد ستون های جدول و پارامتر سوم اگر TRUE باشه جدول خاصیت resize پیدا می کنه و اندازه خونه های جدول برابر با اندازه بزرگترین widget می شه و اگر FALSE باشه دیگه این امکان وجود نخواهد داشت .
    نکته ای که اینجا وجود داره نحوه شماره گذاری سطر ها و ستون ها در جدول هست که از صفر شروع می شه مثلا برای یک جدول 2 در 2 شماره سطر و ستون ها بدین شکل خواهد بود .


    خوب هون طور که گفته بودم برای ایجاد هر widget به سه خط کد احتیاج داریم الان برای ایجاد یک جدول کدها مون می شه این
    GtkWidget  *table1;
    table1=gtk_table_new(2 ,2 ,FALSE) ;
    gtk_widget_show(table1);

    خوب حالا برای اینکه widget های خودمون رو در خانه های جدول قرار بدیم از تابع زیر استفاده می کنیم
    gtk_table_attach_defaults(GTK_TABLE(name) , widget name , left_attach , right_attach , top_attach , bottom_attach ) ;

    که به جای name نام جدول به جای widget name هم نام اون widget که می خوام در جدول قرار بدیم و پارامتر های دیگه اون هم مشخصات اون سلولی از جدول هست که می خوایم widgt رو توش قرار بدیم
    استفاده از جدول برای قرار دادن widget ها کمی مشکل هست نه از جهت کد بلکه تنظیم مکان قرار گرفتن widget ها در خانه های ان به همین علت من زیاد به اون نمی پردازم فکر کنم در همین حد هم کافی باشه این هم یک مثال از کاربرد اون
    #include <gtk/gtk.h>
    int main(int argc , char *argv[]){
    gtk_init(&argc,&argv);
    GtkWidget *window ;
    GtkWidget *table ;
    GtkWidget *button1;
    GtkWidget *button2;
    window= gtk_window_new(GTK_WINDOW_TOPLEVEL);
    table=gtk_table_new(1,2,FALSE);
    gtk_container_add(GTK_CONTAINER(window),table);
    button1=gtk_button_new_with_label(“BUTTON 1”);
    button2=gtk_button_new_with_label(“BUTTON 2”);
    gtk_table_attach_defaults(GTK_TABLE(table),button1 ,0,1,0,1);
    gtk_table_attach_defaults(GTK_TABLE(table),button2 ,1,2,0,1);

    gtk_widget_show(window);
    gtk_widget_show(table);
    gtk_widget_show(button1);
    gtk_widget_show(button2);
    gtk_main();
    return 0;
    }

    توجه کنید که شما اول باید با استفاده از تابع gtk_container_add جدول را در پنجره قرار دهید سپس هر یک از دکمه ها را در جدول
    در ضمن بجای این چهار خط کد
    gtk_widget_show(window);
    gtk_widget_show(table);
    gtk_widget_show(button1);
    gtk_widget_show(button2);

    می تونید از تابع زیر استفاده کنید که همون کار رو انجام میده
    gtk_widget_show_all(window);

  4. #4
    روش دوم بسته بندی widget ها با استفاده از جعبه ها :
    این روش پرکاربردترین روش بسته بندی هست که به دو شکل افقی یا عمودی صورت می گیره که برای قرار دادن اونها از چپ به راست یا برعکسش از جعبه افقی که با تابع gtk_hbox_new() ایجاد میشه و برای قرار دادن اونها در پنجره از بالا به پایین یا برعکسش از جعبه عمودی که با تابع gtk_vbox_new() ایجاد میشه انجام میشه . و برای قرار دادن widget ها در جعبه ها هم از توابع gtk_box_pack_start() برای قرار دادن widget ها از چپ به راست در جعبه افقی و از بالا به پایین در جعبه عمودی یا gtk_box_pack_end() برای قرار دادن widget ها از راست به چپ در جعبه افقی و از پایین به بالا در جعبه عمودی استفاده می کنیم . کار با جعبه ها کمی پیچیده هست و اپشن های فراوانی داره که من سعی می کنم تا اونجایی که خودم فهمیدم و بلدم اینجا بنویسم .
    خوب برای ایجاد جعبه افقی از تابع زیر استفاده می کنیم
    gtk_hbox_new(Boolean , int) ;

    که ارگومان اول بررسی می کنه که ایا سایز هر شی که در اون قرار می گیره یکسان باشه یا نه منظور از سایز در جعبه افقی پهنای هر widget می باشد و ارگومان بعدی میزان فاصله بین دو شی هست که در اون قرار می گیره .
    همون طور که گفتم برای ایجاد هر شی نیاز به سه خط کد هست پس شکل کامل کدش میشه این
    GtkWidget *hbox ;
    hbox=gtk_hbox_new(TRUE , 5);
    gtk_widget_show(hbox);

    خوب برای ایجاد یک جعبه عمودی هم از تابع زیر استفاده می کنیم
    gtk_vbox_new(Boolean , int );

    که ارگومان اول بررسی می کنه که ایا whdget هایی که در اون قرار می گیرند ارتفاع یکسانی داشته باشند یا خیر و ارگومان بعدی هم فاصله بین دو widget رو تنظیم می کنه .

    خوب به توابعی می پردازیم که برای قرار دادن اشیا در جعبه ها استفاده می شن من فقط تابع gtk_box_pach_start رو می گم چون رایج تر هست خوب این تابع هم بشکل زیر هست
    gtk_box_pack_start (GTK_BOX(name) , widget name , Boolean expand , Boolean fill , int padding ) ;

    ارگومان اول نام جعبه ما ارگومان دوم نام عنصری که می خوایم تو جعبه بزاریم ارگومان سوم می گه که ایا اون عناصر تمام فضای اضافی جعبه رو پر کنن یا نه فضای خالی وجود داشته باشه ( توضیحات بیشتر در مثال ها ) ارگومان چهارم می گه که فضای اضافی به سایز اشیا اختصاص داده بشه (TRUE ) یا به جعبه اختصاص داده شه و در اطراف هر شی پراکنده شود ( FALSE ) این گزینه زمانی کار می کنه که ارگومان سوم به TRUE ست بشه و ارگومان اخر هم یه مقدار فضای خالی در اطراف هر شی ایجاد می کنه . اوه تموم شد!!!!
    اگه چیزی نفهمیدید نگران نباشید با شکل و مثال متوجه می شید


    در شکل بالا در نیمه اول ما جعبه های افقی رو ایجاد کردیم با این خصوصیات اول اینکه اشیا دارای سایز یکسان نباشند و دیگه اینکه بینشون فاصله نباشه . gtk_hbox_new(FALSE , 0 )
    خوب حالا به کدی که برای قرار دادن هر شی در اون جعبه در ردیف اول استفاده کردیم توجه کنید
    gtk_box_pack_start (GTK_BOX(hbox) , button, FALSE, FALSE, 0) ;

    خوب در این کد ما ارگومان سوم رو False کردیم یعنی گفتیم که فضای اضافی به جعبه اختصاص داده بشه و ارگومان چهارم روهم False کردیم و گفتیم که این فضای خالی باقی مانده برای جعبه باشه .
    در ردیف پایین ترش ما از کد زیر استفاده کردیم
    gtk_box_pack_start (GTK_BOX(hbox) , button, TRUE, FALSE, 0) ;

    در این کد ما ارگومان سوم را به TRUE ست کردیم یعنی گفتیم که فضای خالی باقیمانده به اشیا اختصاص داده بشه بدین شکل که فضای خالی باقی مانده جعبه بر تعداد اشیا تقسیم می شه و هر شی در وسط سهم خودش قرار می گیره مشاهده می کنید که در اطراف هر شی یک فضای خالی ایجاد شده .
    کد ردیف پایین ترش بدین شکل هست
    gtk_box_pack_start (GTK_BOX(hbox) , button, TRUE, TRUE, 0) ;

    ما ارگومان چهارم رو به TRUE ست کردیم این یعنی چی یعنی اینکه بر طبق ارگومان سوم فضای خالی به شی تخصیص داده شده حالا بر طبق ارگومان چهارم این فضایی که به هر شی تخصیص داده شده جزیی از سایز اون شی بشه که در شکل مشاهده می کنید که دیگه فضای خالی وجود نداره و اندازه اشیا بزرگ تر شده .

    خوب در ادامه ما اومدیم یک جعبه ایجاد کردیم با خصوصیات زیر که اشیا سایز یکسانی داشته باشن و بینشون فاصله نباشه . gtk_hbox_new(TRUE , 0)
    خوب در ردیف اول برای قرار دادن اشیا در اون کد زیر رو بکار بستیم
    gtk_box_pack_start (GTK_BOX(hbox) , button, TRUE, FALSE, 0) ;

    یعنی این که فضای خالی به اشیا داده بشه ولی به سایز اشیا اضافه نشه همون طور که می بینید در این صورت دیگه اشیا دارای اندازه های یکسانی نمی شن و ارگومان اول جعبه ما از کار میفته .
    در ردیف بعدی کد زیر رو بکار بستیم
    gtk_box_pack_start (GTK_BOX(hbox) , button, TRUE, TRUE, 0) ;

    یعنی اینکه فضای خالی به اشیا اختصاص داده بشه و فضای اختصاص داده شده جزیی از اندازه اون شی بشه در اینجا چون ارگومان اول جعبه ما به TRUE ست شده این فضا طوری بین اشیا توزیع می شه که همه دارای سایز یکسانی شن .
    خوب دیگه فکر کنم در مورد این روش بسته بندی دیگه توضیح کافی باشه . امیدوارم مطلب رو فهمیده باشید !!!

  5. #5
    اموزش gtk قسمت پنجم :
    دیدم برای بسته بندی با جعبه مثال نزدم اینم مثال
    مثال :
    #include <gtk/gtk.h>
    int main(int argc , char *argv[]){
    gtk_init(&argc,&argv);
    GtkWidget *window ;
    GtkWidget *hbox ;
    GtkWidget *button1;
    GtkWidget *button2;
    window= gtk_window_new(GTK_WINDOW_TOPLEVEL);
    hbox=gtk_hbox_new(TRUE , 0);
    gtk_container_add(GTK_CONTAINER(window),hbox);
    button1=gtk_button_new_with_label(“BUTTON 1”);
    button2=gtk_button_new_with_label(“BUTTON 2”);
    gtk_box_pack_start (GTK_BOX(hbox) , button1, TRUE, TRUE, 0) ;
    gtk_box_pack_start (GTK_BOX(hbox) , button2, TRUE, TRUE, 0) ;

    gtk_widget_show(window);
    gtk_widget_show(hbox);
    gtk_widget_show(button1);
    gtk_widget_show(button2);
    gtk_main();
    return 0;
    }

    حالا برای اینکه نکته ای رو هم گفته باشم این رو از من داشته باشید برای مخفی کردن یک widget در پنجره می تونید به جای استفاده از تابع gtk_widget_show(widget) از تابع gtk_widget_hide(widgt) استفاده کنید .
    نکته ای دیگه اینکه وقتی شما دارید راهنمای gtk رو می خونید با انواعی رو به رو می شید مثل gint یا gchar اینها چی هستن اینها همان انواع معروف int یا char هستن که برای افزایش قابلیت حمل پذیری برنامه ها و برای اینکه بر روی انواع توزیع ها با معماری های مختلف قابل اجرا باشند بدین شکل دوباره تعریف شده اند و مال کتابخانه glib هستن که اون کتابخانه رو هم چون زیر مجموعه این gtk هستن در اینده ای نزدیک معرفی می کنم .

  6. #6
    رویداد ها
    مثال
    #include <gtk/gtk.h>
    void hello(GtkWidget *widget , gpointer data ){
    g_print("WELLCOME TO MY PROGRAM");
    }

    int main(int argc , char *argv[]){
    gtk_init(&argc,&argv);
    GtkWidget *window ;
    GtkWidget *hbox ;
    GtkWidget *button1;
    GtkWidget *button2;
    window= gtk_window_new(GTK_WINDOW_TOPLEVEL);
    hbox=gtk_hbox_new(TRUE , 0);
    gtk_container_add(GTK_CONTAINER(window),hbox);
    button1=gtk_button_new_with_label("BUTTON 1");
    button2=gtk_button_new_with_label("BUTTON 2");
    gtk_box_pack_start (GTK_BOX(hbox) , button1, TRUE, TRUE, 0) ;
    gtk_box_pack_start (GTK_BOX(hbox) , button2, TRUE, TRUE, 0) ;
    g_signal_connect( G_OBJECT(button1) , "clicked" , G_CALLBACK(hello),NULL) ;
    g_signal_connect_swapped(G_OBJECT(button1),"clicke d" ,G_CALLBACK(gtk_widget_show) , G_OBJECT(button2));
    gtk_widget_show(window);
    gtk_widget_show(hbox);
    gtk_widget_show(button1);

    gtk_main();
    return 0;
    }

    قبل از بررسی مثال یه سری مطالب هست که باید گفته شه .
    سیگنال و callback
    هر دکمه ای که فشار داده میشه هر کلیک و امثال این رویداد ها یک سیگنال ایجاد میشه و تابع ای که به این سیگنال جواب میده یا به عبارتی مخاطب این سیگنال هست می گن callback این توضیح عامیانه و سادش هست .
    برای اینکه برای یک widget تولید سیگنال کنیم توابع زیادی وجود داره که پرکاربرد ترین و عام ترین تابع برای این کار تابع زیر می باشد .
    g_signal_connect( G_OBJECT(object name) , event name , G_CALLBACK(func) , func data ) ;

    ارگومام اول یک ابجکت هست که در واقع نام اون widget هست که می خواهیم برای ان یک سیگنال ایجاد کنیم ارگومان دوم رشته ای هست از نوع اشاره گر const gchar * name که معادل (const char *name) هست و نام رویدادی هست که می خواهیم برای ان widget ایجاد کنیم که لیست رویداد هایی که می توانید برای هر widget استفاده کنید در راهنمای کتابخانه موجود است من هم سعی می کنم بیشترش رو بگم ارگومان سوم نام تابعی هست که مخاطب این سیگنال ایجاد شده است و ارگومان اخر هم اطلاعاتی هست که می خوایم به تابعی که مخاطب سیگنال هست فرستاده بشه که از نوع gpointer هست .
    که برای ایجاد یک رویداد کلیک برای یک دکمه تابعی که ایجاد این سیگنال می کنه می شه مثل شکل زیر
    g_signal_connect(G_OBGECT(button),”clicked”,G_  CALLBACK(hello) , NULL) ;

    خوب حالا برای این سیگنال پارامتر های تابع callback باید به شکل زیر باشه
    void callback_func( GtkWidget *widget, gpointer   callback_data );

    که پارامتر اول اون widget که سیگنال رو ایجاد کرده دریافت می کنه و پارامتر دوم هم برای دریافت اطلاعاتی هست که توسط ارگومان چهارم تابع سیگنال فرستاده شده .
    که مثلا برای مثال قبل تابع callback میشه به شکل زیر
    Void hello(GtkWidget *widget , gpointer data )

    خوب یه نوع تابع دیگه ای که برای تولید سگنال استفاده میشه تابع زیر هست
    g_signal_connect_swapped(G_OBJECT(object name),”event name“  ,G_CALLBACK(func namr) , G_OBJECT(name2));

    که همه ارگومان هاش مثل تابع قبلی هست جز اخرین مورد که widgt هست که می خوایم به تابع بفرستیم . از این تابع زمانی استفاده می کنیم که بجای اون widgt که براش این سیگنال رو ساختیم widgt دیگه ای به تابع ارسال بشه مثل وقتی که دکمه فشار داده میشه به جای اینکه دکمه به عنوان پارامتر اول تابع callback ارسال بشه ارگومان چهارم مثلا یک label به تابع callback ارسال میشه برای این تابع شکل تابع callback باید بدین شکل باشه
    void callback_func( GtkObject *object );

    که تنها یک پارامتر داره اون هم شی است که مقدارش برابر ارگومان چهارم تابع سیگنال هست .
    خوب دیگه الان مثالی که براتون زدم همه چیزش برای شما باید واضح باشه جز تابه g_print که برای نوشتن یک متن در کنسول ازش استفاده می شه . داستان رویداد ها هنوز ادامه داره ادامه در پست بعد .

  7. #7
    در این قسمت چند تا از توابع دیگه که مربوط به این مبحث میشه رو معرفی می کنم
    #define             gtk_signal_lookup(name,object_type)

    که ارگومان اولش نام رویدادی هست که شما دنبالش هستید و ارگومان دوم نوع شی است که این سیگنال رو ایجاد کرده که اگه موفق به پیدا کردن چنین سیگنالی در برنامه نشه مقدار صفر را برمی گرداند مثال
    Int a=gtk_signal_lookup(“clicked” , GTK_TYPE_BUTTON);

    که مقدار برگشتی این تابع در اینجا a به عنوان signal id شناخته می شه . کاربرد این تابع هم در واقع بدست اوردن همین عدد هست که به عنوان ارگومانی برای توابع دیگه بکار میره .
    #define             gtk_signal_name(signal_id)

    خوب این تابع هم یک ارگومان داره و اون هم سگنال ایدی هست که توسط تابع قبلی بدست می یاد و کارش هم این هست که نام سیگنالی که توسط این ایدی ایجاد میشه را بر می گرداند مثلا
    Const gchar *a= gtk_signal_name(signal_id);

    که کاربرد عملی این تابع هم بیشتر در برنامه های بزرگ معلوم میشه
    #define             g_signal_handler_disconnect (object,handler_id)

    این تابع هم برای قطع سیگنال ایجاد شده بکار میره که ارگومان اولش اون شی هست که سیگنال رو ایجاد کرده و ارگومان دومش هم مقدار بازگشتی هست که از تابع g_signal_connect بدست می اید هست . مثلا
    #include <gtk/gtk.h>
    #include <iostream>
    using namespace std;
    int a;
    void hello(GtkWidget *widget , gpointer data ){
    g_print("WELCOME TO MY PROGRAM");
    }
    void hi( GtkObject *object ){
    g_signal_handler_disconnect (object,a);
    }

    int main(int argc , char *argv[]){
    gtk_init(&argc,&argv);
    GtkWidget *window ;
    GtkWidget *hbox ;
    GtkWidget *button1;

    GtkWidget *button2;
    window= gtk_window_new(GTK_WINDOW_TOPLEVEL);
    hbox=gtk_hbox_new(TRUE , 0);

    gtk_container_add(GTK_CONTAINER(window),hbox);
    button1=gtk_button_new_with_label("BUTTON 1");

    button2=gtk_button_new_with_label("BUTTON 2");
    gtk_box_pack_start (GTK_BOX(hbox) , button1, TRUE, TRUE, 0) ;
    gtk_box_pack_start (GTK_BOX(hbox) , button2, TRUE, TRUE, 0) ;
    a=g_signal_connect( G_OBJECT(button1) , "clicked" , G_CALLBACK(hello),NULL) ;
    g_signal_connect_swapped( G_OBJECT(button2) , "clicked" , G_CALLBACK(hi),G_OBJECT(button1)) ;
    gtk_widget_show(window);
    gtk_widget_show(hbox);
    gtk_widget_show(button1);
    gtk_widget_show(button2);
    gtk_main();
    return 0;
    }

    اول دکمه 1 رو فشار بدید متنی در کنسول چاپ میشه دکمه دو رو فشار بدید از این لحظه به بعد هر چی دکمه یک رو فشار بدید دیگه کار نمی کنه .
    #define             g_signal_handlers_disconnect_by_func (object,func,data);

    این هم کار تابع قبلی رو انجام می ده فقط ارگومان هاش فرق داره که ارگومان دوم نام تابعی هست که مخاطب سیگنال ایجاد شده هست مثلا
    g_signal_handlers_disconnect_by_func (object , hello , NULL);

    توابع دیگه ای هم وجود داره که زیاد کاربردی نیستن اونها رو دیگه خودتون برید تو راهنمای کتابخانه ببینید .
    اخرین مطلبی که در این مبحث به اون اشاره می کنم اینه

    • button_press_event
    • button_release_event
    • scroll_event
    • motion_notify_event
    • delete_event
    • destroy_event
    • expose_event
    • key_press_event
    • key_release_event
    • enter_notify_event
    • leave_notify_event
    • configure_event
    • focus_in_event
    • focus_out_event
    • map_event
    • unmap_event
    • property_notify_event
    • selection_clear_event
    • selection_request_event
    • selection_notify_event
    • proximity_in_event
    • proximity_out_event
    • visibility_notify_event
    • client_event
    • no_expose_event
    • window_state_event


    اگه تابع callback ما شامل این رویداد ها باشه برای ایجاد سیگنال برای انها از تابع g_signal_connect استفاده می کنیم و شکل تابع callback هم بصورت زیر میشه
    gint callback_func( GtkWidget *widget, GdkEvent  *event, gpointer   callback_data );

    که پارامتر اول نام ان widget هست که براش این سیگنال رو ایجاد کردیم و پارامتر اخر هم اطلاعاتی هست که می خوایم به تابع ارسال کنیم اما پارامتر دوم مقدارش می تونه یکی از موارد زیر باشه این که کدوم به کدوم هست رو وقتی که دارم تک تک widget ها رو بررسی می کنم می گم
    GDK_NOTHING
    GDK_DELETE
    GDK_DESTROY
    GDK_EXPOSE
    GDK_MOTION_NOTIFY
    GDK_BUTTON_PRESS
    GDK_2BUTTON_PRESS
    GDK_3BUTTON_PRESS
    GDK_BUTTON_RELEASE
    GDK_KEY_PRESS
    GDK_KEY_RELEASE
    GDK_ENTER_NOTIFY
    GDK_LEAVE_NOTIFY
    GDK_FOCUS_CHANGE
    GDK_CONFIGURE
    GDK_MAP
    GDK_UNMAP
    GDK_PROPERTY_NOTIFY
    GDK_SELECTION_CLEAR
    GDK_SELECTION_REQUEST
    GDK_SELECTION_NOTIFY
    GDK_PROXIMITY_IN
    GDK_PROXIMITY_OUT
    GDK_DRAG_ENTER
    GDK_DRAG_LEAVE
    GDK_DRAG_MOTION
    GDK_DRAG_STATUS
    GDK_DROP_START
    GDK_DROP_FINISHED
    GDK_CLIENT_EVENT
    GDK_VISIBILITY_NOTIFY
    GDK_NO_EXPOSE
    GDK_SCROLL
    GDK_WINDOW_STATE
    GDK_SETTING
    مثلا برای رویداد button_press_event شکل تابع سیگنال می شه
    g_signal_connect (G_OBJECT (button), "button_press_event",
    G_CALLBACK (button_press_callback), NULL);


    و شکل تابع callback می شه
    static gint button_press_callback( GtkWidget      *widget, 
    GdkEventButton *event,
    gpointer data );

    یکی نیست به من کمک کنه تکی ادم خسته می شه ؟ در ضمن فکر کنم زیاد اینجا gtk طرفدار نداره

  8. #8
    مثال:
    #include <gtk/gtk.h>

    void hello( GtkWidget *widget,
    gpointer data )
    {
    g_print ("Hello World\n");
    }

    gint delete_event( GtkWidget *widget,
    GdkEvent *event,
    gpointer data )
    {

    g_print ("delete event occurred\n");

    return TRUE;
    }

    void destroy( GtkWidget *widget,
    gpointer data )
    {g_print("destroy event occurred");
    gtk_main_quit ();
    }

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

    GtkWidget *window;
    GtkWidget *button;
    gtk_init (&argc, &argv);
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
    g_signal_connect (G_OBJECT (window), "delete_event",
    G_CALLBACK (delete_event), NULL);
    g_signal_connect (G_OBJECT (window), "destroy",
    G_CALLBACK (destroy), NULL);
    gtk_container_set_border_width (GTK_CONTAINER (window), 10);

    button = gtk_button_new_with_label ("Hello World");

    g_signal_connect (G_OBJECT (button), "clicked",
    G_CALLBACK (hello), NULL);

    g_signal_connect_swapped (G_OBJECT (button), "clicked",
    G_CALLBACK (gtk_widget_destroy),
    G_OBJECT (window));

    gtk_container_add (GTK_CONTAINER (window), button);

    gtk_widget_show (button);
    gtk_widget_show (window);
    gtk_main ();
    return 0;
    }

    خوب این هم یک مثال کامل برای رویداد ها بیشتر قسمت های این مثال برای شما باید اشنا باشه و اما سایر قسمت ها
    gtk_widget_destroy(widget);

    این تابع برای حذف یک widget بکار میره ولی اگه widget ما یک پنجره باشه برای اجرای کاملش به یک تابع مثل شکل زیر نیاز داره
    void destroy( GtkWidget *widget,
    gpointer data )
    {
    gtk_main_quit ();
    }

    چون تابع ما تنها می تونه اون widget رو حذف کنه ولی نمی تونه حلقه gtk_main رو به پایان برسونه وقتی این تابع اجرای میشه مقداری رو بر می گردونه که بر اساس ان تابع destroy وارد عمل میشه برای امتحان هم که شده شما تابع destroy رو از برنامه حذف کنید مشاهده می کنید که با اجرای برنامه و کلیک دکمه ظاهرا پنچره حذف و برنامه خاتمه می یابد ولی پنجره کنسول هنوز باز هست و اماده دریافت اطلاعات هست علتش هم این هست که ما هنوز از حلقه gtk_main خارج نشدیم از تابع زیر برای خروج از حلقه استفاده می کنیم
    gtk_main_quit ();

    خوب تابع دیگه ای که تو برنامه داریم
    gint delete_event( GtkWidget *widget,
    GdkEvent *event,
    gpointer data )
    {

    g_print ("delete event occurred\n");

    return TRUE;
    }

    که چون ما از رویداد delete_event استفاده کردیم به همین علت تابع callback ما به شکل بالا هست و مقدار بازگشتی این تابع TRUE یا FALSE هست که اگه TRUE باشه دیگه تابع destroy اجرا نمی شه اما اگه FALSE باشه موجب اجرای تابع destroy و خروج از برنامه میشه تابع delete_event هنگامی فراخوانی میشه که شما دکمه close برنامه رو فشار بدید توجه داشته باشید که تابع destroy یا زمانی که شما دکمه موجود در برنامه رو فشار بدید و یا زمانی که شما دکمه close برنامه رو فشار بدید اجرا میشه با این مثال قضیه رویداد ها تموم شد هر widget رویداد های خاص خودش رو داره و شما هم می تونید خودتون یک widget یا یک رویداد جدید بسازید که در اینده اون ها رو هم توضیح می دم .

  9. #9
    کاربر دائمی آواتار ravand
    تاریخ عضویت
    اردیبهشت 1389
    محل زندگی
    راوند کاشان
    پست
    3,378

    نقل قول: اموزش برنامه نویسی با gtk

    ببخشید این مقاله نحوه نصب gtk در ویندوز و پیکربندی ان برای کامپایل برنامه ها با ویژوال سی پلاس پلاس لینکش کجاست؟

قوانین ایجاد تاپیک در تالار

  • شما نمی توانید تاپیک جدید ایجاد کنید
  • شما نمی توانید به تاپیک ها پاسخ دهید
  • شما نمی توانید ضمیمه ارسال کنید
  • شما نمی توانید پاسخ هایتان را ویرایش کنید
  •