لطفا وارد شوید یا ثبت‌نام کنید تا به انجمن‌ها دسترسی کامل داشته باشید.



 
امتياز موضوع :
  • 0 رأي - معدل امتيازات : 0
  • 1
  • 2
  • 3
  • 4
  • 5
آموزش توابع Qt قسمت هفتم
2004-08-26, 03:29 AM,
ارسال : #1
آموزش توابع Qt قسمت هفتم
فصل هفتم : One Thing Leads to Another

اين مثال چگونگي ساختن اشياء سفارشي داراي سيگنالها و اسلاتها و همچنين چگونگي اتصال آنها به يكديگر توسط روشهاي پيچيده تر را نشان مي دهد. در ابتدا، متن برنامه در بين چند فايل تقسيم شده است.
[ltr]Lcdrange.h[/ltr]
[ltr]
کد :
#ifndef       LCDRANGE_H
#define      LCDRANGE_H

#include      <qvbox.h>

class      QSlider;

class      LCDRange   :    public      QVBox
{
    Q_OBJECT
    public :
        LCDRange ( QWidget     *parent = 0 , const    char     *name = 0 );
        int     value( )   const;
    public    slots:
        void   setValue ( int );
    signals :
        void    valueChanged ( int );
    private :
        QSlider      *slider;
};

#endif     //  LCDRANGE_H
[/ltr]

[ltr]lcdrange.cpp[/ltr]
[ltr]
کد :
#include       “lcdrange.h”
#include       <qslider.h>
#include       <qlcdnumber.h>

LCDRange::LCDRange ( QWidget     *parent , const   char    *name )   :   QVBox ( parent , name )
{
    QLCDNumber       *lcd = new     QLCDNumber  ( 2 , this , “lcd” );
    slider = new    QSlider ( Horizontal , this , “slider” );
    slider -> setRange ( 0 , 99 );
slider -> setValue ( 0 );
connect ( slider , SIGNAL ( valueChanged ( int ) ) , lcd , SLOT ( display ( int ) ) );
connect ( slider , SIGNAL ( valueChanged ( int ) ) , SIGNAL ( valueChanged ( int ) ) );
}

int     LCDRange::value( ) const
{
    return      slider -> value( );
}

void   LCDRange::setValue( int value )
{
    slider -> setValue ( value );
}
[/ltr]

[ltr]main.cpp[/ltr]
[ltr]
کد :
#include      <qapplication.h>
#include      <qpushbutton.h>
#include      <qlcdnumber.h>
#include      <qfont.h>
#include      <qvbox.h>
#include      <qgrid.h>
#include      “lcdrange.h”

class      MyWidget   :    public    QVBox
{
    public :
        MyWidget ( QWidget     *parent = 0 , const   char   *name = 0 );
};

MyWidget::MyWidget ( QWidget    *parent , const    char   *name )  :  QVBox ( parent , name )
{
    QPushButton      *quit = new    QPushButton ( “Quit” , this , “quit” );
quit -> setFont ( QFont ( “Times” , 18 , QFont::Bold ) );
connect ( quit , SIGNAL ( clicked ( ) ) , qApp , SLOT ( quit ( ) ) );
QGrid    *grid = new    QGrid ( 4 , this );
LCDRange    *previous  = 0;
for   ( int  r = 0 ; r < 4 ; r ++ ) {
    for   ( int  c = 0 ; c < 4 ; c ++ ) {
        LCDRange    *lr = new     LCDRange ( grid );
        if  ( previous )
            connect ( lr , SIGNAL ( valueChanged ( int ) ) , previous , SLOT ( setValue ( int ) ) );
        previous = lr;
    }
}
}

int      main ( int   argc , char   **argv )
{
    QApplication    a ( argc , argv );
    MyWidget    w;
a.setMainWidget ( &w );
w.show ( );
return      a.exec( );
}
[/ltr]
بررسي خط به خط برنامه:
فايل lcdrange.h كلاً از main.cpp از فصل ششم گرفته شده است. تنها تغيير آن اينجا بيان شده است :
[ltr]
کد :
#ifndef      LCDRANGE_H
#define     LCDRANGE_H
[/ltr]
اين يك تركيب كلاسيك C جهت اجتناب از خطا در زماني كه سرفايل بيش از يك بار ضميمه شده باشد. اگر تا حالا از آن استفاده نمي كرديد، اين يك عادت خوب براي پيشرفت است. #ifndef بايد تمام سرفايل ها را ضميمه كند.
[ltr]
کد :
#include      <qvbox.h>
[/ltr]
qvbox.h ضميمه شده است. LCDRange ، QVBox را به ارث مي برد، و سرفايل كلاس والد بايد هميشه ضميمه شده باشد. ما در فصلهاي قبلي كمي تقلب كرديم، و ما اجازه داديم qwidget.h بصورت غير مستقيم توسط سرفايلهاي ديگر از قبيل qpushbutton.h ضميمه شده باشد.
[ltr]
کد :
class      LCDRange  :  public   QVBox
{
    Q_OBJECT
    public :
        LCDRange   (QWidget      *parent = 0 , const  char   *name = 0);
[/ltr]
به Q_OBJECT توجه كنيد. اين ماكرو بايد در همه كلاسهايي كه شامل سيگنالها و يا اسلاتها هستند ضميمه شده باشد. اگر شما كنجكاو هستيد، اين ماكرو تابعهايي را كه در يك متاشيء (meta object) پياده سازي شده اند، تعريف مي كند.
[ltr]
کد :
        int     value( )   const;
    public    slots:
        void   setValue ( int );
    signals :
        void    valueChanged ( int );
[/ltr]
اين سه عضو يك رابط رابين شيء و ديگر مؤلفه ها در يك برنامه ايجاد مي كنند. تا حالا، LCDRange واقعاً هيچگونه رابطي نداشته است.
value ( ) يك تابع عمومي براي دستيابي به متغير value از شيء LCDRange است. setValue ( ) اولين اسلات سفارشي ما و valueChange( ) نيز اولين سيگنال سفارشي ما است. اسلاتها بايد در يك راه و روش معمولي پياده سازي شده باشند( بخاطر داشته باشيد كه يك اسلات همچنين يك تابع عضو C++ است ). سيگنالها بطور خودكار در متاشيء ( meta object ) پياده سازي شده اند. سيگنالها از قوانين دسترسي محافظت شده در C++ پيروي مي كنند ( يعني ، آنها تنها توسط كلاسي كه در آن تعريف شده اند و كلاسهايي كه از آن مشتق مي شوندمي توانند مورد استفاده قرار گيرند) . سيگنال valueChanged( ) همانطوري كه از روي نام آن حدس مي زنيدزماني كه مقدار LCDRange تغيير مي كند استفاده مي شود. اين تنها سيگنالي نيست كه شما آنرا با تركيب somethingChanged( ) خواهيد ديد.
فايل lcdrange.cpp كلاً از فايل main.cpp فصل ششم گرفته شده است، تنها تغييرات آن اينجا بيان شده است:
[ltr]
کد :
connect ( slider , SIGNAL ( valueChanged ( int ) ) , lcd , SLOT ( display ( int ) ) );
connect ( slider , SIGNAL ( valueChanged ( int ) ) , SIGNAL ( valueChanged ( int ) ) );
[/ltr]
اين كد از سازنده LCDRange مي باشد. دستور connect اول همانند آنهايي است كه در فصلهاي پيش ديده ايد. ولي دومي جديد است. اين فرمان سيگنال valueChanged ( ) اسلايدر را به سيگنال valueChanged ( ) شيء this متصل مي كند. Connect ( ) با سه آرگومان هميشه به سيگنالها و يا اسلاتهاي شيء this متصل مي گردد. بله، اين درست است. سيگنالها مي توانند به ديگر سيگنالها متصل شوند. وقتي كه اولي منتشر شد، دومي نيز منتشر مي شود.اجازه دهيد بنگريم وقتي كه كاربر اسلايدر را اداره مي كند چه اتفاقي مي افتد. اسلايدر متوجه مي شود كه مقدارش تغيير كرده و سيگنال valueChanged( ) را منتشر مي كند. آن سيگنال به اسلات display( ) از شيء QLCDNumber و نيز valueChanged( ) از شيء LCDRange متصل شده است. بنابراين، زماني كه سيگنال منتشر شد، LCDRange سيگنال valueChanged( ) خودش را منتشر مي كند. بعلاوه، QLCDNumber::display( ) فراخواني شده و يك عدد جديد را نمايش مي دهد. توجه كنيد كه ضمانت نمي شود كه در زمان اجرا ترتيب رعايت گردد – LCDRange::valueChanged ( ) ممكن از قبل از QLCDNumber::display ( ) منتشر شود و كاملا اختياري و خودسرانه است.
[ltr]
کد :
int     LCDRange::value( ) const
{
    return      slider -> value( );
}
[/ltr]
پياده سازي value ( ) سرراست و مشخص است، بسادگي مقدار اسلايدر را باز مي گرداند .
[ltr]
کد :
void   LCDRange::setValue( int value )
{
    slider -> setValue ( value );
}
[/ltr]
همچنين پياده سازي setValue ( ) نيز سرراست است. توجه كنيد، بخاطر اينكه اسلايدر و LCDNumber به هم متصل شده اند، تنظيم مقدار اسلايدر بطور خودكار به خوبي LCDNumber را به روز مي كند. بعلاوه ، اسلايدر بصورت خودكار زماني كه مقدار از محدوده مورد قبول خود تجاوز كرد، آنرا تنظيم مي كند.
فايل main.cpp.
[ltr]
کد :
LCDRange    *previous  = 0;
for   ( int  r = 0 ; r < 4 ; r ++ ) {
    for   ( int  c = 0 ; c < 4 ; c ++ ) {
        LCDRange    *lr = new     LCDRange ( grid );
        if  ( previous )
            connect ( lr , SIGNAL ( valueChanged ( int ) ) , previous , SLOT ( setValue ( int ) ) );
        previous = lr;
    }
}
[/ltr]
تمام main.cpp بجز سازنده MyWidget از فصل قبل كپي شده است. وقتي ما 16 شيء LCDRange ساختيم، آنها را با مكانيسم سيگنال/اسلات به هم متصل مي كنيم. هريك سيگنال valueChanged ( ) خود را به اسلات setValue ( ) قبلي متصل كرده است. ما دراينجا يك زنجيره از سيگنالها و اسلاتها ساخته ايم، چون LCDRange زماني كه مقدارش تغيير مي كند سيگنال valueChanged( ) خود را منتشر مي كند.

كامپايل برنامه :
ساختن Makefile براي يك برنامه متشكل از چندفايل با ساختن آن براي برنامه تك فايلي فرقي نمي كند. اگر شما تمام فايلهاي اين مثال را در دايركتوري خودشان ذخيره كرده ايد تنها كاري كه بايد انجام دهيد اين است:
[ltr]
کد :
qmake    -project
qmake
[/ltr]
اولين دستور به qmake مي گويد كه يك فايل .pro پروژه بسازد. دستور دوم با آن مي گويد كه يك Makefile مبتني بر فايل پروژه بسازد. حالا شما قادريد تا با تايپ make ( يا nmake اگراز visual Studio استفاده مي كنيد) برنامه خود را بسازيد.

عملكرد برنامه:
در زمان بالاآمدن، ظاهر برنامه با برنامه قبلي يكسان است. سعي كنيد كه اسلايدر را به سمت پايين و راست ببريد.

تمرينات :
از اسلايدر پايين سمت راست براي تنظيم تمام LCDها به عدد 50 استفاده كنيد. سپس مقدار بالا و وسطي را با يكبار كليك در سمت چپ دستگيره اسلادر به 40 تنظيم كنيد. حالا، از يكي از اسلايدرها براي بازگرداندن مقدار هفت LCD اول به 50 استفاده كنيد. برقسمت سمت چپ دستگيره اسلايدر پايين و سمت راست كليك كنيد. چه اتفاقي مي افتد؟ چرا اين يك عملكرد درست است؟
حالا شما براي فصل هشتم آماده هستيد.
[/b]
جستجوی تمامی ارسال های کاربر
نقل قول این ارسال در یک پاسخ
2004-09-06, 11:17 AM,
ارسال : #2
 
مرسی .. جدا ممنونم ...

[ltr]
$Nəvid$
In a world without any fences or walls,
Who needs gates or windows ?
گنو ایران | لیست مقالات فارسی گنو ایران |
[/ltr]
مشاهده تارنمای کاربر جستجوی تمامی ارسال های کاربر
نقل قول این ارسال در یک پاسخ
2004-09-06, 01:41 PM,
ارسال : #3
 
دستتون درد نکنه . پشتکارتون تحسین داره.


irix@Hell:~$ mkfs -t Free /body/.mind && mount -o rw /body/.mind /FreeMind
مشاهده تارنمای کاربر جستجوی تمامی ارسال های کاربر
نقل قول این ارسال در یک پاسخ
2004-09-07, 01:37 AM,
ارسال : #4
آموزش توابع Qt قسمت هفتم
با عرض سلام و با تشکر از زحمات شما
اگر میشد این برنامه رو با تصاویری از ان اموزش میدادید خیلی عالی میشد

باز هم تشکر Big Grin Big Grin
مشاهده تارنمای کاربر جستجوی تمامی ارسال های کاربر
نقل قول این ارسال در یک پاسخ


رفتن به انجمن :


کاربران در حال مشاهده موضوع : 1 مهمان