PDA

View Full Version : آموزش: آموزش کیوت به زبان ساده



.:saeed:.
دوشنبه 05 مهر 1389, 00:42 صبح
با سلام
با اجازه از بزرگان این انجمن ، بنده پیش دستی میکنم و این کار رو شروع میکنم اما این به این معنی نیست که من باید تمام کارو انجام بدم ، همه با هم ، هرکی هر چی بلده رو البته با نظمی که در این آموزش جلو میریم تو سایت قرار بده ، مثلا فردا کسی نیاد از برنامه نویسی شبکه در کیوتی بگه :لبخند:
فکر کردم اگه آموزش ها به صورت فایل پی دی اف برا دانلود قرار داده بشه بهتره ، چون کیفیت کار میتونه بالاتر بره .
خوب قسمت اول که یک introduction و یک مختصری از سی پلاس پلاس هستش ( البته تا سر موضوع کلاس ها چون کلاس ها تو کیوت مهمه گفتم در یک آموزش جدا گونه به اون پرداخته بشه )رو آماده کردم .تقدیم به دوستان خوبم. لطفا نظراتتون رو منتقل کنید . خودتون هم می دونین شرط ادامه این جور کارها نظرات دیگران ، ابراز احساسات ، بیان نظرات و انتقادات و سوالات آنهاست .
چون نمیشه بیشتر از 400 کیلو تو سایت آپلود کرد از یه سایت دیگه استفاده کردم

دانلود قسمت اول آموزش (http://www.4shared.com/file/wPH8Z8ih/qt1.html)(660 کیلو بایت )
دانلود قسمت دوم آموزش( آموزش مقدمات سی پلاس پلاس - کلاس ها ) (http://www.4shared.com/file/n1O-VghM/qt2.html)
موفق باشید

Open-Source
دوشنبه 05 مهر 1389, 10:08 صبح
خوبه.
اینجور کارها خیلی خوب و پسندیده هستش.
شما به کارت ادامه بده.
اگه بنده و دیگر دوستان هم بتونیم کمک میکنیم.
من دیگه اینجا پست نمیدم ، چون دوست ندارم نظم این تاپیک از بین بره (از دوستان هم همین خواهش رو دارم).
:تشویق:

.:saeed:.
دوشنبه 05 مهر 1389, 15:22 عصر
سلام ، ممنون از نظرت ، فقط به من بگيد به همين فرمت ( پي دي اف ) راحت تريد يا اين که مستقيم تو سايت قرار بدم ؟

Open-Source
دوشنبه 05 مهر 1389, 21:13 عصر
به فرمت PDF , MTML خوبه.
از DOC استفاده نکن.

.:saeed:.
جمعه 09 مهر 1389, 02:26 صبح
سلام
آموزش - قسمت دوم - کلاس ها در سی پلاس پلاس ( قسمت اول ) ( برگرفته از کتاب C++‎‎ How To Program , Daitel, 5th edition)
دانلود (http://www.4shared.com/file/n1O-VghM/qt2.html)
موفق باشید.:چشمک:

.:saeed:.
شنبه 17 مهر 1389, 00:58 صبح
با سلام
شرمنده از اینکه دیر شد.
چون دیدم از مقدمه سی پلاس پلاس زیاد استقبال نشد گفتم حتما دوستان در این مورد مشکلی ندارند . خوب اونو skip کردم و رفتم سر اصل مطلب . قسمت بعدی مقدماتی از کیوتی و محیط ها و نرم افزارهای همراه کیوتی به صورت کلی معرفی شدند . بررسی و آموزش هر کدام ، ان شاءالله در ادامه مباحث خواهد آمد
دانلود (http://www.4shared.com/file/SGWRPkTK/Qt3.html)قسمت سوم از آموزش کیوتی ( مقدمات و محیط های همراه )
موفق باشید.

.:saeed:.
شنبه 17 مهر 1389, 01:07 صبح
سلام .
در بین آموزش ها اگه تونسم ، منابعی غیر از اونایی که خودم آماده میکنم رو هم براتون میذارم
مقاله ای که میذارم یک معرفی اجمالی از کیوت ، تاریخچه و خیلی چیزای جالبه ، 30 صفحه به زبان انگلیسی
دانلود (http://www.4shared.com/file/TqvlBdfX/01-QtIntroduction.html)
موفق باشید

.:saeed:.
سه شنبه 21 دی 1389, 01:17 صبح
سلام از غیبت طولانی ( اگه مهم بود ! ) شرمنده
HelloWorld In Qt Part A (http://qtuts.mihanblog.com/post/11)
HelloWorld In Qt Part B (http://qtuts.mihanblog.com/post/14)
QPushButton (http://qtuts.mihanblog.com/post/16)

glassysmart
سه شنبه 21 دی 1389, 23:43 عصر
سلام
این (http://qt.nokia.com/services-partners/qt-in-education/qt-in-education-course-material) را هم ببینید

.:saeed:.
چهارشنبه 22 دی 1389, 18:59 عصر
QLineEdit (http://qtuts.mihanblog.com/post/17)
QHBoxLayout, QVBoxLayout (http://qtuts.mihanblog.com/post/18)

ghasem.fattahpour
پنج شنبه 23 دی 1389, 09:51 صبح
دستت درد نکنه. من خیلی وقت بود دنبال یک همچین چیزی بودم. تشکر

.:saeed:.
پنج شنبه 23 دی 1389, 17:46 عصر
آموزش بعدی
QGridLayout (http://qtuts.mihanblog.com/post/19)


می خواستم بدونم نظرتون چیه آموزش ها به صورت فیلم بشه !؟ پیشاپیش ممنون از پاسخ ها تون

.:saeed:.
یک شنبه 26 دی 1389, 15:52 عصر
Signals and Slots part one
(http://qtuts.mihanblog.com/post/20)Signals and Slots part Two
(http://qtuts.mihanblog.com/post/21)ساختن ویدجت دلخواه ( به صورت ویدیو ) (http://qtuts.mihanblog.com/post/22)
نوشتن اسلات دلخواه(به صورت ویدیو ) (http://qtuts.mihanblog.com/post/23)

.:saeed:.
یک شنبه 26 دی 1389, 17:14 عصر
مدیریت حافظه در سلسله مراتب اشیا


همون طور که میدونید سی پلاس پلاس مدیریت حافظه رو به عهده برنامه نوس گذاشته است یعنی اینکه وقتی شما به عملگر new یه شی ی رو ایجاد میکنید این شی از بین نمیره تا یا برنامه به انتها برسه یا از عملگر delete برای حذف اون استفادن کنیم
اما در کیوتی این امکان وجود داره که...


ادامه مطلب (http://qtuts.mihanblog.com/post/24)

.:saeed:.
یک شنبه 26 دی 1389, 17:52 عصر
کلاس های پایه در کیوتی


کلاس هایی که از QObject ارث میبرند:
هم مبحث مدیریت حافظه خودکار و هم مبحث signal / slot نیاز مند...
کلاس هایی که از QObject ارث نمی برند:
اما خوب مسلما همه کلاس ها نیازمند مکانیزم سیگنال و اسلات و مدیریت حافظه خودکار نیستند...
Implicit sharing(Value-based Memory Management )
کیوتی یه جور دیگه ای برای مدیریت حافظه اشیایی که کلاسشون از QObject ارث نبرده اقدام میکنه ( البته نه همه کلاس ها ) ...

ادامه مطلب (http://qtuts.mihanblog.com/post/25)

.:saeed:.
یک شنبه 26 دی 1389, 18:31 عصر
کتابخانه های کیوتی


ممکنه یه سوال مهم مطرح بشه و اون اینه که آیا کیوتی فقط قابل استفاده برای ساخت یه user interface ساده است ؟ ایا کیوتی فقط شکل نمایش برنامه ما رو به کاربر دلپذیر تر میکنه ؟ یا نه ; قابلیت های دیگه ای هم به ما میده...
QtCore
QtGui
QtSql
QtNetwork
...


ادامه مطلب (http://qtuts.mihanblog.com/post/26)

.:saeed:.
یک شنبه 26 دی 1389, 19:29 عصر
ابزار ها و امکانات مکمل کیوتی


Qt اسمی کوچک و دنیایی بزرگ!
همراه کتابخانه های کیوتی مجموعه ای از ابزار هایی تعبیه شده که کار برنامه نویسی با کیوتی را برای شما ساده تر و دلپذیر تر میکنه دراین مقاله قصد داریم با آنها آشنا بشیم
QtAssistant
QtDesigner
QtLinguist

ادامه مطلب (http://qtuts.mihanblog.com/post/27)

.:saeed:.
یک شنبه 26 دی 1389, 19:30 عصر
Meta-object Compiler moc

مفهوم سیگنال و اسلات موجود در کیوتی یه مفهوم محض سی پلاس پلاس نیست...
Property system
ادامه مطلب (http://qtuts.mihanblog.com/post/28)

.:saeed:.
یک شنبه 26 دی 1389, 20:53 عصر
Qt Resources Compiler rcc

شاید هیچ برنامه با واسط کاربری گرافیکی پیدا نشه که از منابعی مثل تصاویر و فایل های گرافیکی توش استفاده نشده . مثل آیکن های تولبار و منو بار یا...
ادامه مطلب (http://qtuts.mihanblog.com/post/29)

.:saeed:.
یک شنبه 26 دی 1389, 21:41 عصر
چگونه با کمک رسان کیوتی کار کنیم(به صورت ویدیو)

دستیار و کمک رسان شما در مورد برنامه نویسی با کیوتی کمک رسان کیوتی خواهد بود . در این فایل ویدیویی با بخش های مختلف اون آشنا میشیم
ادامه مطلب (http://qtuts.mihanblog.com/post/30)

.:saeed:.
دوشنبه 27 دی 1389, 19:12 عصر
مثال : برنامه مبدل مبنا


مثال امروز ما در مورد یک برنامه بسیار ساده است که یه عدد دهدهی رو از ورودی میگیره و مقدار های مبنای ۱۶ و ۲ اونو نشون میده...
http://dc303.4shared.com/img/d5vUWRo1/s3/0.8004251048622213/convertor.png

ادامه مطلب (http://qtuts.mihanblog.com/post/31)

.:saeed:.
دوشنبه 27 دی 1389, 19:54 عصر
بررسی مقادیر وارد شده توسط کاربر
معمولا ما خیلی از ورودی های مورد نیازمون رو از کاربر میگیریم حالا چه با استفاده از QLienEdit یا بااستفاده از ویدجت های دیگه که برای این کار در نظر گرفته شده است.

نکته ای که هست اینه که ممکنه کاربر مقداری رو وارد بکنه که از دید ما و برنامه ما یه مقدار invalid یا غیر معتبر باشه مثلا توی مثال قبلی اگر کاربر به جای اینکه یه عدد رو وارد بکنه یه سری حروف وارد بکنه مسلما برای ما داده های معتبری نخواهد بود . برای اینکه کاربر رو محدود بکنیم که تنها اون چیزی رو که مد نظرماست ; اون محدوده ای از اعدا د که مد نظر ماست ; اون رشته ای که با الگوی خاصش مدنظر ماست (مثل ایمیل ) رو وارد بکنه در کیوتی از کلاس های Validator استفاده میکنیم .

QIntValidator:
برای بررسی اینکه ایا مقدار ورودی کاربر یه عدد دهدهی هست از این کلاس و شی ساخته شده از این کلاس استفاده میکنیم . به این صورت که :

QIntValidator* decValidator = new QIntValidator(0, 255, decEdit);
decEdit->setValidator(decValidator);

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

سومین متغیر هم تعیین کننده پدر این validator هستش.طبق مطالبی که قبلا گفته شد در این صورت تا مادامی که شی پدر یعنی decEdit که یه QLineEdit هستش زنده هست ارزیاب اون هم یعنی decValidator زنده است. تابع setValidator هم برای تعیین یه validator برای یه QLineEdit هستش . بعد از این مرحله decValidator چشم میدوزه به مقادیر ورودی در decEdit هر موقع مقادیر وارد شده از شرط ما تخطی کردند مقدار جدید در decEdit وارد نخواهد شد.

QRegExpValidator:

با استفاده از این کلاس و قدرت regular expression ها شما به راحتی میتونید چک کنید ( برای مثال )‌که آیا آدرس ایمیل وارد شده از طرف کاربر مجاز هست; آیا عدد باینری وارد شده توسط کاربر مجاز هست ; آیا عدد هگزای وارد شده توسط کاربر مجاز هست یا نه ; و صد ها مثال دیگه .
اما مفهوم regular expression چیه : regular expressions یا عبارات باقاعده مجموعه قوانینی هستند که با استفاده از اونا شما میتونید الگویی که رشته میتونه داشته باشه رو تعیین کنید . برای مثال ببینید آیا الگوی ایمیل به صورت زیر هست یا نه

(یک یا بیشتر حرف یا رقم).(یک یا بیشتر حرف یا رقم)@(صفر یا بیشتر حرف یا رقم)(یک حرف)
البته ممکنه برخی قواعد رو من رعایت نکرده باشم ولی میخواستم با مفهوم آشنا بشیم. ما با reg exps این الگو رو تعریف میکنم و فرضا به QLineEdit دستور میدیم تنها براساس این الگو میتونی کاراکتر بگیری ولاغیر .یعنی مثلا حق نداری در ابتدا یه رقم بگیری و ...
البته regular expressions یکم پیچیده هستند و تسلط بر مبحث عبارات با قاعده زمان میبره که میتونید به
این آدرس برای یادگیری اونا مراجعه کنید

QRegExpValidator* hexValidator =new QRegExpValidator(QRegExp("[0-9A-Fa-f]{1,2}"), hexEdit);
hexEdit->setValidator(hexValidator);
مثل مثال قبلی ما یه شی از کلاس QRegExpValidator ساختم و در سازنده شی ای از کلاس QRegExp رو براش فرستادیم . چون مبحث regular expression ها بسیار پر کاربرد هستش درکیوتی برای کاربا آنها یک کلاس تعریف شده به نام QRegExp . الگویی که ما قصد داریم مقادیر ورودی بر اساس اونا باشه با سازنده کلاس QRegExp ارسال میشه که در انیجا الگویی برای تشخیص اعداد هگزا دسیمال هستش.
مثلا مفهوم متن الگوی ما در این مثال یعنی اینکه ورودی باید حداقل یک کاراکتر صفر تا نه یا A تا F یا a تا f و حداکثر دو کاراکتر با همان ویژگی ها باشه که قابل پذیرش باشه

نه خسته !

.:saeed:.
چهارشنبه 29 دی 1389, 23:00 عصر
QMainWindow قسمت اول (http://qtuts.mihanblog.com/post/34)
در این قسمت سعی داریم با یکی از مهمترین کلاس های مجموعه کیوتی اشنا بشیم و اونم QMainWindow هستش . اما

QMainWindow چیست ؟

هر گاه شما قصد داشته باشید که یک برنامه کامل رو طراحی کنید ، هر گاه شما نیاز داشته باشید که برنامه تون شکل استانداردی داشته باشه ، هر گاه برنامه تون نیاز به منو بار و یا تولبار و یا statusbar داره ، در واقع و در اصل شما نیاز به یه main window پیدا کردین . پس main window کامل ترین نوع یک فرم در کیوتی هستش یعنی فرمی که میتونه منوبار و تولبار و ... رو داشته باشه . این ویژگی در QWidget و QDialog وجود نداره . در شکل زیر یه MainWindow رو میبینید.

http://dc302.4shared.com/img/aXDXvzDo/s7/0.041522337247542174/Mainwindow.png


#include <QApplication>
#include <QMainWindow>
#include <QLabel>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow mainWindow;
QLabel *label =new QLabel("<center>Central Widget</center>");
mainWindow.setCentralWidget(label);
mainWindow.show();
return a.exec();
}

این یه مثال ساده از QMainWinow هست .

توجه کنید که QLabel توانایی پردازش تگ های html رو داره . یعنی شما میتونید یه متن فرمت شده با html رو توی یه Label نمایش بدین و نکته دیگه تابع setCentralWidget هستش . هر QMainWindow میتونه یه ویدجت مرکزی داشته باشه که در واقع قسمت اصلی یه برنامه است و در کل QMainWindow پخش میشه . مثلا توی برنامه نقاشی ویدجت مرکزی میتونه یه بوم برای نقاشی باشه.

گفتن این نکته خالی از لطف نیست که برنامه های بزرگ معمولا از QMainWindow ارث برده و بنا به نیاز خودشون به اون ویژگی هایی اضافه میکنند که در قسمت های بعدی به اون اشاره میکنیم.

خسته نباشید

.:saeed:.
پنج شنبه 30 دی 1389, 00:37 صبح
QMainWindow قسمت دوم
ارث بری از کلاس QMainWindow
سلام خدمت دوستان عزیز
در قسمت قبلی با کلاس QMainWindow به طور مختصر آشنا شدیم . خوب ذکر این نکته مهمه که معمولا برنامه های بزرگ تر به شیوه ای که در مثال قبلی دیدیم نوشته نمیشند. بلکه در برنامه های جدی تر و مهم تر ما از کلاس QMainWindow ارث میبریم و ویژگی های مورد نیازمون رو بهش اضافه میکنیم
یه مثال خیلی ساده رو با هم بررسی میکنیم . فرض کنید میخوایم یه کلاس به نام MainWindow (‌ کیو نداره) درست کنیم که از کلاس QMainWindow ارث برده شده باشه . خوب اول ساده ترین قسمت کد رو با هم ببینیم




#include <QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow mainWindow;
mainWindow.show();
return a.exec();
}



خوب کد بالا فقط برای ساختن یه شی از کلاس ماست . که خیلی شبیه مثال قبلیه با این تفاوت که هر چیزی که قراره در داخل MainWindow ماقرار بگیره باید به فایل MainWindow.cpp و سازنده اون منتقل بشه و در main ما تنها یه شی از اون میسازیم و با تابع show() نمایشش میدیم.

فایل MainWindow.h ما به شکل زیر خواهد بود





#include <QMainWindow>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
};



خوب همون طور که از کد پیداست ما از کلاس QMainWindow ارث بردیم. Q_OBJECT رو هم که توی moc گفتیم . اگه کلاس شما حاوی سیگنال و اسلاتی باشه که خودتون تعریف میکنید این ماکرو حتما باید ذکر بشه. اما عادت خوبیه حتی اگه شما سیگنال و اسلات خودتون رو هم تعریف نکردید ولی این ماکرو رو توی فایل .h تون قرار بدین.( شاید تجربه کرده باشید که چرا میگم خوب عادتیه )




#include "mainwindow.h"
#include <QLabel>
MainWindow::MainWindow()
{
setWindowTitle(tr("MyFirstMainWindow"));
resize(400, 400);
QLabel* label = new QLabel(tr("Central Widget"));
setCentralWidget(label);
label->setAlignment(Qt::AlignCenter);
}


فرض کنید سازنده ی این کلاس هم به صورت بالا باشه .
تابع اول چیه ؟ window title عنوان بالای پنجره شما رو تعیین میکنه مثلا اگه از مرور گر firefox استفاده میکنید window title شما یه چیزی شبیه Mozila FireFox هستش که در کنار دکمه های بستن و ... هستش. برای تعیین window title یه main window از این تابع استفاده میکنیم . این تابع عضو کلاس QMainWindow هستش و چون شما به صورت public از این کلاس ارث بردین مسلما بهش دسترسی دارین.
چیزی که توی این تابع به چشم میخوره استفاده از یه تابع دیگه به نام tr هستش . این تابع خیلی کاربردیه . چرا ؟ با عادت به این کار که هر رشته ای که تو برنامه تون هست رو داخل این تابع قرار بدین ، به صورت ضمنی دارین رشته هاتونو برای ترجمه به زبان های دیگه تعیین میکنید. یعنی چی ؟ خوب اگه شما بخواید برنامه ای که نوشتید رو به زبان های مختلف توسعش بدین کار ساده ای نخواهد بود چون یک به یک باید اونا رو جایگزین کنید یا مثل بعضی از برنامه ها از فایل های خارجی استفاده کنید . اما در کیوتی با تعیین رشته هایی که باید ترجمه شوند و استفاده از برنامه linguist که بعدا آموزشش رو باهم میبینیم میتونید به راحتی برنامه تون رو به هر زبانی تر جمه کنید
تابع بعدی که استفاده شده resize هستش که برای تغییر عرض و ارتفاع یه ویندو هستش . به ترتیب عرض و ارتفاع رو به عنوان پارامتر به این تابع ارسال میکنیم . بعد از انجام این دستور ، پنجره ما عرض 400 و ارتفاع ۴۰۰ خواهد داشت.
تو خط بعدی کد من اومدم یه QLineEdit رو روی heap گرفتم تا به main window خودم اضافه کنم . چرا با new این کارو انجام دادم ؟‌چون که اگه روی استک میگرفتم خوب بعد از اینکه سازنده تموم میشد به طبع QLineEdit ساخته شده هم از بین میرفت.
تابع setCentralWidget هم که قبلا توضیحشو دادیم .فقط یه نکته یادم رفت بگم اینکه با اجرای این تابع ، main window پدر ویدجتی میشه که به عنوان پارامتر به این تابع ارسال شده یعنی اونو مدیریت میکنه و در
زمان مقتضی پاکش میکنه.
برای اینکه متن لاین ادیت هم در وسط نمایش داده بشه از تابع setAlignment استفاده کردیم .
نکته آخر این که اگه شما بخواین ویدجت مرکزی تون یه کم پیچیده تر و در عین حال مرتب باشه میتونید این کارو بکنید که ابتدا یه شی از QWidget بسازید بعدش روی این ویدجت هر چی دلتون خواست ویدجت های دیگه مثل QLineEdit , QPushButton و.. با استفاده از layout ها بچینید و بعد اون ویدجت رو به عنوان ویدجت
مرکزی انتخاب کنید
فعلا

.:saeed:.
پنج شنبه 30 دی 1389, 01:53 صبح
QMainWindow قسمت سوم
ساخت یک ویرایشگر متن ساده - قسمت اول
سلام خدمت دوستان عزیز
خوب با مقدمات QMainWindow آشنا شدیم . برای اینکه main window ما دارای منوبار ، تولبار و ... باشه دو راه داریم . یکی استفاده از Qt Designer هستش و دیگری کد نویسی و خوب به طبع کسی که دومی رو بدونه دیگه اولی براش کاری نداره . ما در ادامه قصد داریم با هم ، مرحله به مرحله ، یه ویرایشگر متن خیلی ساده بنویسیم تا از این طریق با قسمت های مختلف یه main window آشنا بشیم .
خوب من یه empty project ساختم (File - > New File Or Project -> Other Project -> Qt empty projet ) به نام QNotePad و بعدش یه فایل main.cpp و یه کلاس QNotePad که از QMainWindow ارث برده بهش اضافه
کردم.
کد QNotePad.h به صورت زیر خواهد بود




#ifndef QNOTEPAD_H
#define QNOTEPAD_H

#include <QMainWindow>
class QPlainTextEdit;
class QNotePad : public QMainWindow
{
public:
QNotePad();

private:
QPlainTextEdit *m_plainTextEdit;
};

#endif // QNOTEPAD_H


برای کار با متن های یه خطی از QLineEdit استفاده میکنیم . ولی اگه متن چند خطی شد باید از QTextEdit استفاده بشه . نکته ای که هست اینه که QTextEdit توانایی پذیرش متن های فرمت شده رو داره . یعنی چی یعنی متنی که یه جاش blod شده یا مثلا متنی که رنگ یه جاش با بقیه فرق میکنه . و حتی جالبتر این که شما میتونید یه متنی که با html فرمت شده رو به QTextEdit بدین . اما چون ما میخوایم خیلی ساده کار کنیم از QPlainTextEdit استفاده کردیم که فقط متن های ساده قبول میکنه.

فایل QNotePad.cpp من هم به صورت زیر خواهد بود.




#include "QNotePad.h"
#include <QPlainTextEdit>

QNotePad::QNotePad()
{
setWindowTitle(tr("QNotePad"));
m_plainTextEdit = new QPlainTextEdit;
setCentralWidget(m_plainTextEdit);
}


که مثل مثال قبلیه . فقط من QPlainTextEdit رو به صورت اشاره گری عضو کلاس تعریف کردم تا اگه جای دیگه ای در کلاس بهش نیاز داشتم مشکلی نداشته باشم.( البته از تابع centralWidget هم میشد استفاده کرد!)
خوب تا اینجا که مثل قبل بود ولی خوب ما قصد داریم به این برنامه چندین منو و تولبار و status bar اضافه کنیم که به مرور با هم این کارو انجام میدیم.
فقط من یه پیش زمینه ای بگم و کار رو از جلسه بعدی آغاز میکنیم.
در برنامه نویسی و ایجاد یه main window یه چیزی زیاد به گوش میخوره ( منظورم در کیوتی هستش ) که QAction نام داره . QAction چیه ؟ یه مثال شما وقتی میخواید تلویزیون رو روشن کنید دو تا راه دارید یا از remote control استفاده کنید یا به صورت مستقیم با دکمه ای که روی خود تلویزیون هست. هر دوی اینا یه کارو انجام میدن اونم تلویزیون رو روشن میکنند . حالا در مورد خاموش کردن هم همین طور با این تفاوت که یه راه دیگه هم هست که دوشاخو رو از پریز در بیاریم :لبخند: یا فیوز رو قطع کنیم :قهقهه: . باز هم همه اینها یه کار رو انجام میدند ، تلویزیون رو خاموش میکنند . توی کیوتی نگاه کنید حالا :‌من میخوام یه فایل متنی رو درون این ویرایش گرم باز کنم چند تا راه دارم : یکی اینکه از منوی فایل گزینه open رو بزنم ، یا اگه توی تولبار ایکنش هست ،‌ایکنش رو بزنم ،‌یا از ctrl+o استفاده کنم . باز هم همه اینها یک کار میکنه . به این یک کار توی کیوتی میگند Action . شما یه Action تعریف میکنید ( مثلا اکشن باز کردن یه فایل )‌و بعد جاهای مختلف ازش استفاده میکنید مثلا توی منو یا تولبار .پس اساس تعریف منو و تولبار در کیوتی QAction هست که بعدا باهاش بیشتر اشنا میشیم.
کد پروژه تا اینجا ضمیمه شد
65296

.:saeed:.
پنج شنبه 30 دی 1389, 12:54 عصر
QMainWindow قسمت چهارم
ساخت یک ویرایشگر متن ساده - قسمت دوم

سلام دوستان عزیز . اولا تشکر میکنم از حامد عزیز به خاطر اینکه این تاپیک رو اعلان کردند و دوما بریم سر آموزش !
خوب تا این جا رفتیم که برای افزودن منو و تولبار به main window با مفهومی به نام action روبرو هستیم . جلسه قبلی با مفهومش آشنا شدیم حالا بریم سراغ کاربردش.

ایجا منو در یک QMainWindow
برای ایجاد منو بار در کیوتی چندین کلاس درگیر خواهندشد . QMenuBar , QMenu, QAction . هر QMainWindow یی یه QMenuBar فعال داره که این QMenuBar شامل چندین QMenu میشه و هر QMenu شامل چندین QAction . پس QMenuBar حاوی تمامی منوهای یک اپلیکیشن خواهد بود و هر QMenu حاوی چندین Action .
به صورت پیش فرض هر QMainWindow حاوی یه QMenuBar هستش که از طریق تابع menuBar() شما میتونید به اشاره گری از اون دسترسی پیدا کنید . وقتی که شما به یه QMenuBar دسترسی دارین با استفاده از تابع addMenu عضو کلاس QMenuBar میتونید به این منوبار یه منو اضافه کنید . فرض کنید فایل QNotePad.cpp ما به صورت زیر باشه



QNotePad::QNotePad()
{
....
createMenus();
}


void QNotePad::createMenus()
{
QMenu *fileMenu = menuBar()->addMenu("File");
m_newFileAction = fileMenu->addAction("New");
m_openFileAction = fileMenu->addAction("Open");
m_saveFileAction = fileMenu->addAction("Save");
m_exitAction = fileMenu->addAction("Exit");
}


و فایل QNotePad.h به صورت زیر




#include <QMainWindow>
class QPlainTextEdit;
class QAction;
class QNotePad : public QMainWindow
{
public:
QNotePad();

private:
QPlainTextEdit *m_plainTextEdit;
QAction *m_newFileAction;
QAction *m_openFileAction;
QAction *m_saveFileAction;
QAction *m_exitAction;
void createMenus();

};

#endif // QNOTEPAD_H



بخش های غیر ضروری حذف شدند . راه های مختلفی برای انجام این کاری که من انجام دادم هست که در آخر نتیجه یکی خواهد بود. خوب توی فایل .h من چهار تا اشاره گر به QAction ساختم . این اکشن ها همون طور که گفتم وظیفه انجام کاری رو دارند که ممکنه از چندین راه ، درخواستی برای انجام وظیفه شون براشون صادر بشه. مثلا اولی برای ایجاد یه سند خالی هستش که ممکنه از طریق های زیر صدا زده بشه
۱.ازطریق منوی فایل
۲.ازطریق Ctrl+N
۳.ازطریق تولبار
چون قصد داریم این اکشن ها بعدا در تابعی که ذکر خواهدشد به تولبار هم اضافه بشند اونارو به صورت عضو کلاس تعریف
کردیم . و حالا تابع createMenus که تابع عضو کلاس QNotePad هست که من خودم برای ساختن منو ها استفاده کردم.




void QNotePad::createMenus()
{
QMenu *fileMenu = menuBar()->addMenu("File");
m_newFileAction = fileMenu->addAction("New");
m_openFileAction = fileMenu->addAction("Open");
m_saveFileAction = fileMenu->addAction("Save");
m_exitAction = fileMenu->addAction("Exit");
}

خوب همونطور که گفتم تابع menuBar عضو کلاس QMainWindow اشاره گری به منوبار جاری برمیگردونه . و با استفاده از تابع addMenu عضو کلاس QMenuBar ما یه منو به منوبارمون اضافه میکنیم. پارامتر ارسالی به تابع نام منو رو تعیین میکنه . پارامتر های دیگه ای هم میشه ارسال کرد که فعلا مورد بحث ما نیست.این تابع اشاره گری به منوی ایجاد شده بر میگردونه که ما اونو توی fileMenu نگهش میداریم .
حال با استفاده از تابع addAction عضو کلاس QMenu به منوی فایل مون اکشن های دلخواهمون رو اضافه میکنیم. باز هم همون شیوه افزودن منو اینجا تکرار شده . یعنی با استفاده از تابع addAction ما به منوی فایلمون یه اکشن اضافه میکنیمو اشاره گرش رو نگه میداریم ( بعدا از این اشاره گر استفاده خواهیم کرد ) . حالا کافیه که با ctrl+r پروژه تون رو ( اگه تو creator هستید در غیر این صورت با توجه به ide ) اجرا کنید تا نتیجه رو ببینید . البته فراموش نکنید که فایل QNotePad.pro شما حاوی خط زیر باشه .


QT+= gui core


این خط کتابخانه اصلی کیوتی و کتابخانه gui رو به پروژه تون اضافه میکنه . اینکه ساختار و کاربرد فایل .pro چیه بعدا بیشتر باهم بحث میکنیم .

سعی کنید خودتون منو ها و اکشن های دیگه ای به منوبار اضافه کنید.
شاید سوالات زیادی براتون پیش اومده که مثلا چه طوری یه short key به اکشن نسبت بدم یا چطوری یه اکشن آیکن داشته باشه که همه این ها در آینده بحث خواهد شد ان شا الله:لبخند:

.:saeed:.
شنبه 02 بهمن 1389, 08:51 صبح
با سلام خدمت دوستان عزیز
در قسمت قبلی تونستیم که منو رو به mainwindow اضافه کنیم . حالا قصد داریم به اکشن های داخل منو ها آیکن اضافه کنیم و بعد اونا رو به یه toolbar هم اضافه کنیم.
برای استفاده از منابع (Resources) در برنامه دو راه داریم یا آنها را در پوشه هایی کنار برنامه بذاریم یا اینکه از سیستم منابع کیوتی (Qt Resources system ) استفاده کنیم . گزینه اول مشکلاتی داره از جمله اینکه فایل های شما در دسترس کاربر هست و یا ممکنه از بین بره . اما همون طور که توی بخش کامپایلر منابع کیوتی گفته شد . شما میتونید این فایل ها رو در درون فایل اجرایی تعبیه کنید (Embedded) .در این صورت شما به فایل هاتون دسترسی دارین و دیگران نه !
خوب برای اینکه بتونین از سیستم منابع کیوتی استفاده کنید باید یه فایل دیگه به پروژه تون اضافه کنید با پسوند qrc که با استفاده از گزینه
File->New File or projects->Qt ->Qt Resource File
قابل اضافه شدن به پروژه هست. خوب با اضافه شدن این فایل به پروژه و کلیک کردن روش صحفه برای شما باز میشه که کار اضافه کردن منبع رو به پروژه راحت میکنه. در مورد منابع با دو تا اسم و مفهوم جدید روبرو هستیم . یکی prefix ودیگری alias . در مورد اولی باید بگم که prefix در واقع ابزاری برای پوشه بندی مجازی در یک فایل res هستش . با این کار و با اضافه کردن prefix شما میتونید تصاویر تون رو به دسته های مختلف طبقه بندی کنید.
http://dc190.4shared.com/img/BauC0dl2/s3/res.png

البته میتونید یه prefix بینام هم داشته باشید . خوب با کلیک بر روی گزینه Add files شما میتونید هر نوع فایلی رو به عنوان منبع به برنامه تون اضافه کنید . من چندتا آینکن به برنامه ام اضافه کردم. بهتره منابع تون رو توی یه پوشه به نام Resources در کنار فایل های سرس برنامه تون اضافه کنید . در ضمن در مسیر نصب کیوتی و در پوشه Examples شما میتونید آیکن های متدوال و مورد نیاز رو پیدا کنید.

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




void QNotePad::createMenus()
{
QMenu *fileMenu = menuBar()->addMenu("File");
m_newFileAction = fileMenu->addAction("New");
m_newFileAction->setIcon(QIcon(":/menu_icons/Resources/filenew.png"));
m_newFileAction->setShortcut( QKeySequence::New );

m_openFileAction = fileMenu->addAction("Open");
m_openFileAction->setIcon(QIcon(":/menu_icons/Resources/fileopen.png"));
m_openFileAction->setShortcut(QKeySequence::Open);

m_saveFileAction = fileMenu->addAction("Save");
m_saveFileAction->setIcon(QIcon(":/menu_icons/Resources/filesave.png"));
m_saveFileAction->setShortcut(QKeySequence::Save);

m_exitAction = fileMenu->addAction("Exit");
m_exitAction->setIcon(QIcon(":/menu_icons/Resources/delete.png"));
m_exitAction->setShortcut(QKeySequence("Ctrl+Q"));
}




خوب این تابعی که قبلا نوشتیم رو یه کم تغییر دادیم تا نتایج دلخواه حاصل بشه . اولین تغییر مربوط به استفاده از تابع setIcon مربوط به کلاس QAction هستش . که به اکشن ما یه ایکن نسبت میده . این تابع نیاز به یه شی از کلاس QIcon داره که خوب گرفته دیگه .
نحوه آدرس دهی یه منبع :یک دونقطه + prefix اون منبع + آدرس بعد از prefix .
به تصویر ضمیمه شده نگاه کنید و با نحوه آدرس دهی بالا انطباق بدین تا متوجه بشین.
http://barnamenevis.org/attachment.php?attachmentid=65377&stc=1&d=1295675358
برای کلید میانبر دادن به یک اکشن از تابع setShortcut استفاده میکنیم. این تابع یک شی از کلاس QKeySequence از ما انتظار داره . از طرفی کیوتی برای اینکه شما به راحتی بتونید به استاندارد کلید میانبر دهی کنید برای کلید های پر کاربرد enum در نظر گرفته که شما رو از دادن کلید به صورت صریح راحت میکنه . اما خوب امکانش هست که به صورت صریح این کارو انجام بدین که در آخرین setShortcut قابل مشاهده هست. ذکر این نکته مهمه که در آخرین setShortcut ما از یک شی از QKeySequence استفاده کردیم. این شی چند سازنده داره که یکیش از ما یه QString میگیره که کلید ترکیبی (‌یا غیر ترکیبی ) میانبر ماست.

.:saeed:.
یک شنبه 03 بهمن 1389, 08:46 صبح
سلام .خوب دوستان امید وارم که تا حالا خسته نشده باشید و اماده مطالب جدید تری از کیوتی باشید
در جلسات قبل یکی از مهمترین موجودیت های یه برنامه با واسط کاربر گرافیکی رو با هم دیدیم . یعنی طراحی منو . در این قسمت قصد داریم یکی دیگه از بخش های لازم و مورد نیاز یه برنامه گرافیکی رو با هم ببینیم .تولبار. در این جلسه همچنین قصد داریم که به action هایی که در جلسات قبلی ایجاد کردیم جان بدهیم .یعنی اینکه کار دلخواه ما رو انجام بدن.

خوب بهتره کد های این جلسه رو ببینید. اول فایل QNotePad.h . بعضی از قسمت ها حذف شدند.




#ifndef QNOTEPAD_H
#define QNOTEPAD_H

#include <QMainWindow>
class QPlainTextEdit;
class QAction;
class QNotePad : public QMainWindow
{
Q_OBJECT;
public:
QNotePad();

private:
.
.
.
void createMenus();
void createToolbars();
void createConnections();

private slots:
void newDocument();
void openDocument();
void saveDocument();

};



در فایل QNotePad.cpp بخش های مهم به صورت زیر هستند.



void QNotePad::createToolbars()
{
QToolBar *mainToolbar = new QToolBar( this );
mainToolbar->addAction( m_newFileAction );
mainToolbar->addAction( m_openFileAction );
mainToolbar->addAction( m_saveFileAction );
mainToolbar->addAction( m_exitAction );
addToolBar( mainToolbar );
}

خوب برای ساختن یه تولبار باز هم از کلاسی که در کیوتی به این منظور ایجاد شده استفاده میکنیم . و اون کلاس QToolBar هستش که یه شی ازش میسازیم و تنها کار مورد نیاز اضافه کردن اکشن هایی است که قبلا اونارو توی ساختن منو ها ساختیم . با تابع addAction اونارو به تولبار مون اضافه میکنیم . با تابع addToolBar عضو کلاس QMainWindow هم میتونیم یک تولبار رو به main window خودمون اضافه کنیم .

برای اینکه بتونیم از صدا زده شدن یه اکشن با خبر بشیم سیگنال triggered عضو کلاس QAction باید استفاده بشه . این سیگنال زمانی emit میشه که اکشن ما به یه نحوی صدا زده شده باشه یا با استفاده از منو ها یا با استفاده از تولبار یا ... . پس تابع createConnections ما به صورت زیر در میاد.




void QNotePad::createConnections()
{
connect( m_newFileAction, SIGNAL(triggered()), SLOT(newDocument()));
connect( m_openFileAction, SIGNAL(triggered()), SLOT(openDocument()));
connect( m_saveFileAction, SIGNAL(triggered()), SLOT(saveDocument()));
connect( m_exitAction, SIGNAL(triggered()), this, SLOT(close()) );
}



نکته ای که هست در تابع connect اگه گیرنده اسلات کلاس جاری باشه this نیازی به ذکر اون نیست. با تعریف هر یک از این اسلات ها کار دلخواه ما انجام خواهد شد. خوب اینم یه تعریف ساده از اسلات newDocument




void QNotePad::newDocument()
{
m_plainTextEdit->setPlainText("");
}


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

.:saeed:.
دوشنبه 04 بهمن 1389, 08:51 صبح
QMainWindow قسمت هفتم
کار با دیالوگ های استاندارد و فایل ها

سلام دوستان امید وارم که صبح خوبی رو شروع کرده باشید .

در این قسمت قصد داریم اسلات های save و open رو درست کنیم. خوب در این صورت به یک سری کلاس هایی بر میخوریم که در کیوتی با نام Standard Dialogs شناخته میشند . دیالوگ های استاندارد مجوعه ای از کلاس ها هستند که ما رو برای انجام برخی از کارهای استاندارد یاری میکنند . مثلا اگه شما نیاز به گرفتن یه فونت دارین برای یه جای برنامه تون کیوتی کلاسی داره که شما رو برای انتخاب یه فونت راحت میکنه . یا اگه تو برنامه تون نیاز دارین که انتخاب یه رنگ به کاربر سپرده بشه . خوب بهترین کار ممکن اینه که یه پالت رنگ به کاربر نمایش بدین و بعدش بخواین که رنگو انتخاب کنه . باز هم دیالوگی برای این کار هست. اما دیالوگ استانداردی که ما در این قسمت نیاز داری دیالوگ گرفتن یه آدرس برای باز کردن متنیش در برنامه است . همچنین نیاز به دیالوگی داریم که یه آدرس به ما برای ذخیره فایلمون بده. در ضمن در این قسمت نیاز به کار با فایل ها بدر کیوتی داریم . برای کاربا فایل ها در کیوتی کلاس هایی تعبیه شده که اساس همگی اونا کلاسی است به نام QIODevice .

خوب اسلات openDocument تا اینجا به صورت زیر خواهد بود



void QNotePad::openDocument()
{
QString fileName =
QFileDialog::getOpenFileName(this, "Open", "", "Text Files (*.txt);;All Files(*.*)" );
if( !QFile::exists(fileName))
return;

QFile file(fileName );

if (!file.open(QFile::ReadOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream in(&file);
m_plainTextEdit->setPlainText(in.readAll());

}

دیالوگ استانداردی که در این قسمت استفاده میشه QFileDialog هستش که تابع استاتیکی برای گرفتن یه مسیر برای باز کردن از کاربر به کار میره . با اجرای این تابع یک دیالوگ به کاربر نمایش داده میشه و از اون خواسته میشه که آدرس فایل مورد نظرش رو وارد کنه. پارامتر های این تابع : اولی پدرش . دومی عنوان caption دیالوگ نمایش داده شده. سومین پارامتر : مسیری که با نمایش دیالوگ به صورت پیش فرض نمایش داده بشه. و چهارمی فیلتر فایل های نمایش داده شده است .

برای کار با فایل ها در کیوتی سه تا کلاس پر کاربرد داریم یکی QFile و QTextStream و QDataStream . خوب با اولی میتونید یه فایل رو باز کنید و حتی با استفاده از توابعش تو اون فایل بنویسید یا ازش بخونید.کلاس QTextStream در واقع یه اینترفیس روی QFile هستش برای راحت کار کردن با خواندن ونوشتن در فایل های متنی و خوب QDataStream هم همینطور فقط با این تفاوت که برای فایل های باینری به کار میره . باز هم میگم شما برای خوندن یا نوشتن در یه فایل فقط نیاز به QFile دارین . ولی برای راحتتر کار کردن با فایل ها توصیه میشه با استفاده از QTextStream و QDataStream به مقاصدتون برسید.
خوب من از تابع استاتیک exist عضو کلاس QFile استفاده کردم تا تشخیص بدم آیا این فایل معتبره یا نه . (‌ممکنه کاربر اصلا دکمه cancel رو کلیک کنه که در این صورت فایل قابل باز شدن نیست :لبخند:)
در مرحله بعد از کلاس QFile بنده یک شی با ارسال آدرس فایل به سازندش ساختم .
در قسمت بعدی اونو بازش کردم با استفاده از تابع open . به این تابع گفتم که میخوام فایلم به صورت فقط خواندنی QFile::ReadOnly و به صورت متنی QFile::Text باز بشه و چون این ها پرچم هستند قابلیت or شدن باهم رو دارند. اما اگه تابع open با شکست مواجه شد. مقدار بازگشتیش false خواهد بود که ما با استفاده از QMessageBox اینو به اطلاع کاربر میرسونیم .

اما یه نکته خیلی کاربردی : در اشیایی که QString هستند یا QString برمیگردونن مثل tr ( باز هم همون QString مورد بحث خواهد بود ) میشود از تابع arg عضو کلاس QString استفاده های خیلی خوبی برد. این تابع متن فعلی QString ای که با اون فراخونده شده رو میگره و جای number% پارامتری که براش ارسال شده رو میذاره . اینکه کدوم number با پارامتر ما جایگزین بشه بستگی به این داره که ما در مرتبه چندم از .arg() استفاده کردیم .




QMessageBox::warning(this, tr("Application"),
tr("Cannot read file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));


مثلا در این جا درصد یک با fileName جایگزین میشه . درصد دو با خروجی تابع errorString . این تابع آخرین خطای یه QFile رو به صورت QString بر میگردونه .تابع .arg عضو کلاس QString بسیار پرکاربرد است . به خصوص در برنامه نویسی برای پایگاه های داده.



QTextStream in(&file);
m_plainTextEdit->setPlainText(in.readAll());

در این قسمت از کد هم ما یه QTextStream برای کار کردن راحت تر با فایل ساختیم و بعد با استفاده از تابع readAll اون که تمام متن یه فایل رو به صورت یه QString برمیگردونه و استفاده از setPlainText عضو کلاس تکست ادیتمون به نتیجه دلخواه رسیدیم.
خسته نباشید .اسلات save برای بعد .

ghasem.fattahpour
سه شنبه 05 بهمن 1389, 09:14 صبح
با احترام
از زحمت شما کمال قدر دانی را دارم. یک سوال:

آیاقابلیت RTL شدن (راست به چپ شدن) در این کامپوننت ها وجود ندارد؟
چونکه من مثال های شما را فقط در حالت LTR می بینم. اگر محدودیتی در این زمینه وجود دارد راهنمایی بفرمایید.
تشکر

.:saeed:.
سه شنبه 05 بهمن 1389, 23:00 عصر
دوست عزیز ممنون . سوالاتتون رو در تاپیک های جداگانه مطرح کنید.
در مورد سوالتون هم باید بگم که بله امکان راست به چپ شدن در این widget ها وجود دارد . تابع setLayoutDirection این کارو براتون انجام میده

.:saeed:.
چهارشنبه 06 بهمن 1389, 08:05 صبح
QMainWindow قسمت هشتم
نوار وضعیت Status bar
بنام خدا
خوب در جلسه قبلی در مورد کار با فایل ها در کیوتی و همچنین کار با دیالوگ های استاندارد صحبت کردیم . این قسمت هم سعی داریم که اول اسلات save رو با هم بررسی کنیم و بعدش کار با status bar یا نوار وضعیت رو با هم بررسی کنیم.



void QNotePad::saveDocument()
{
QString fileName =
QFileDialog::getSaveFileName(this, "Open", "", "Text Files (*.txt);;All Files(*.*)" );

QFile file(fileName );

if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot write file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream out(&file);
out << m_plainTextEdit->toPlainText();
}


همون طور که مشاهده میکنید گرفتن یه آدرس برای ذخیره یه فایل مثل بازکردنه . با تابع getSaveFileName که عضو کلاس QFileDialog هستش و در ضمن استاتیک هست این کار قابل انجام هست. بقیه کد هم که خیلی ساده هست هم تکراری است و هم چیزی برای گفتن نداره . در مورد toPlainText فقط توضیح بدم که چون textEdit ها میتونن متن با فرمت داشته باشند (Rich Text) به همین دلیل ممکنه متنشون ساده ساده هم نباشه . با استفاده از این تابع من در واقع دارم متن ساده رو بدست میارم یعنی متنی که هیچ فرمتی نداره .

Status Bar

هر main window ای به صورت پیش فرض حاوی یک نوار وضعیت برای نمایش پیغام ها و یا اطلاع رسانی ها میباشد. که با تابع statusBar() عضو کلاس QMainWindow قابل دسترسی هست.معمولا این پیغام ها در سه دسته طبقه بندی میشوند .
پیغام های موقتی: مثل وقتی که شما رو یکی از گزینه های منوی اکسپلورر تون میرین و متنی در پایین صفحه ظاهر میشه که توضیح دهنده کار این گزینه هست.

پیغام های معمولی : مثل تعداد نمایش تعداد خطوط یا تعداد کلمات در یک ویرایش گر متن.

پیغام های ثابت :‌ این پیغام ها هیچ موقع از بین نمیروند . مثلا در بعضی از برنامه های پیغام ثابتی در status bar وضعیت caps lock رو نمایش میده.

پیغام های موقت Temporary Messages و پیغام های معمولی در سمت چپ یک statusbar ظاهر میشند و پیام های ثابت در سمت راست.

این نوار همچنین یک size grip هم برای ما فراهم کرده . مثلث سمت راستی که برای تغییر اندازه main window قابل استفاده هست. در ضمن با استفاده از تابع (setSizeGripEnabled(false میتونید اونو غیر فعال کنید.
خوب گفتیم که اگه شما از تابع QMainWindow::statusBar() استفاده کنید اشاره گری به status bar براتون برگردونده میشه . اگر هم شما status bar نداشتین این تابع یه status bar جدید ایجاد میکنه و اونو به main window تون اضافه کرده و اشاره گری به اون بر میگردونه .

خوب حالا هر یک از انواع پیام ها رو به صورت جزئی تر بررسی میکنیم.

پیام های موقتی : این پیغام ها برای مدت کوتاهی نمایش داده خواهند شد. این پیام ها با استفاده از QStatusBar::showMessage() که یک اسلات هست در status bar نمایش داده میشند و با استفاده از QStatusBar::clearMessage() پاک میشند. پیام موقت تا زمانی که از این تابع استفاده نشه یا متن جدیدی با showMessage به status bar نسبت داده نشه باقی خواهد ماند. اگه میخواهید که متن موقت شما برای یه مدت زمان ثابتی نمایش داده بشه مثلا ۵ ثانیه میتونید پارامتر دومی برای showMessage که البته اختیاری هم هست ارسال کنید. این عدد باید برحسب میلی ثانیه باشد.

پیغام های معمولی : خوب این پیغام ها به سادگی پیام های موقت نیست. شما باید برای استفاده از این نوع پیام از ویدجت ها استفاده کنید .اگه مثلا شما میخواید که یه متن ساده رو به عنوان یه پیام معمولی استفاده کنید باید اول یه شی از QLabel بسازین و بعد اونو به QStatusBar تون با استفاده از تابع addWidget اضافه کنید . شاید یکم پیچیده تر بشه ولی مزایای خاص خودشو داره. فرضا شما میتونید از آیکن ها در پیامتون استفاده کنید یا اینکه از نوار پیشرفت QProgressBar ( همون نوار های آبی رنگی که از ۰ تا ۱۰۰ پر میشه ) و یا هر ویدجت دیگه ای استفاده کنید.
هدر تابع addWidget( QWidget *widget, int stretch = 0 ) بیان گر اینکه شما باید یک یا دو پارامتر براش ارسال کنید . اولیش که خوب معلومه برای تعیین اشاره گر به ویدجت مد نظر هستش . نکته ای که هست مخرب QStatusBar خودش این ویدجت رو حذف میکنه (delete) . پس باید روی heap گرفته بشه.پارامتر دوم تعیین کننده اینه که فضای status bar چطور بین چند ویدجت های اضافه شده به satus bar تقسیم بشه. اگه شما مقدار صفر پیشفرض رو قبول کنید به این معناست که این ویدجت به اندازه ای که نیاز داره جا بر میداره. اعداد دیگر نسبت تقسیم فضا بین ویدجت ها رو مشخص میکنه . مثلا اگه شما سه تا ویدجت با مقادیر ۱ و ۲ و ۳ برای پارامتر دوم داشته باشید.فضای نسبت داده شده به سومی سه برابر اولی و فضای نسبت داده شده به دومی دو برابر اولی خواهد بود.

پیغام های ثابت :
برای پیام های ثابت تابع addPermanentWidget استفاده میشود.این ویدجت ها در سمت راست به status bar اضافه میشند. تضمین شده که این پیام ها هیچ وقت وقفه ای در نمایششون پدید نیاد.

خوب فرض کنید ما میخوایم به متن ثابت به status bar مون اضافه کنیم که تعداد کلمات و تعداد حروف متن داخل جعبه متنمون رو نمایش بده.برای این کار یه اشاره گر به کلاس QLabel عضو کلاس تعریف میکنم و بعد در سازنده یه شی به اون نسبت میدم و بعدش اونو به status bar خودم اضافه میکنم. در اینجا ما نیاز به یه اسلات دیگه هم داریم که وظیفه اش این که صبر کنه هروقت متن m_plainTextEdit عوض شد مقدار پیام ثابت مارو به روز کنه. برای اینکار
در فایل .h ابتدا یه اشاره گر به یک لیبل اضافه میکنیم




class QNotePad : public QMainWindow
{
Q_OBJECT
public:
QNotePad(QWidget *parent=0);
~QNotePad();


private:
...
...
...
QLabel *m_charWordMessage;

public slots:
...
...
void updateStatusBar();

};







m_charWordMessage = new QLabel;
statusBar()->addPermanentWidget( m_charWordMessage );
connect( m_plainTextEdit, SIGNAL(textChanged()), SLOT(updateStatusBar()) );

این سه خط در سازنده اضافه شدند . اولی که یه شی از QLabel به m_charWordMessage نسبت میده . دومی اونو به عنوان یه متن ثابت به statusbar اضافه میکنه و سومی سیگنال textChanged از کلاس QTextEdit رو به اسلاتی که ما قراره خودمون تعریفش کنیم یعنی updateStatusBar وصل میکنه . این سیگنال زمانی فرستاده میشه که متن یه TextEdit تغییر کنه.




void QNotePad::updateStatusBar()
{
QString text = m_plainTextEdit->toPlainText();
int chars = text.length();
text = text.simplified();
int words = 0;
words = text.count(" ");
if (!text.isEmpty()) words++;
QString output = tr("Characters: %1, Words: %2").arg(chars).arg(words);
m_charWordMessage->setText(output);
}

اینم اسلات updateStatusBar که قراره هر وقت سیگنال textChanged فریاد زده شد بیاد و متن داخل پیام ثابت status bar رو به روز کنه. در این تابع از برخی از توابع QString استفاده شده که به شرح زیر هستند.
تابع QString::length تعداد کاراکترهای متن رو بر میگردونه
تابع QString::count تعداد کاراکتر های / متنهایی که به عنوان پارامتر براش ارسال شده رو در متن اصلی برمیگردونه که ما در این جا با شمردن تعداد فاصله ها ، تعداد تقریبی کلمات رو بدست میاریم.
تابع simplified که خیلی مهم هست: space های ابتدا و انتهای متن رو حذف میکنه . و spaceهای درون متن رو اگه چند تا پشت سر هم باشند با یکی جایگزین میکنه.منظور از فضای خالیt', '\n', '\v', '\f', '\r', ' ' s هستند.

اسلات save رو هم میشه به این صورت تغییر داد تا بعد از ذخیره فایل پیغام موقتی رو در مدت ۵ ثانیه نمایش بده



void QNotePad::saveDocument()
{
QString fileName =
QFileDialog::getSaveFileName(this, "Open", "", "Text Files (*.txt);;All Files(*.*)" );

QFile file(fileName );

if (!file.open(QFile::WriteOnly | QFile::Text)) {
QMessageBox::warning(this, tr("Application"),
tr("Cannot write file %1:\n%2.")
.arg(fileName)
.arg(file.errorString()));
return;
}
QTextStream out(&file);
out << m_plainTextEdit->toPlainText();
statusBar()->showMessage("File Saved", 5000 );
}
[/LEFT]


پروژه ضمیمه شد
خسته نباشید.

.:saeed:.
جمعه 08 بهمن 1389, 00:46 صبح
سلام
خوب تا اینجا تقریبا بیشتر مباحث مربوط به main window رو بررسی کردیم . چند مبحث تکمیلی باقی میمونه که بعدا گفته میشه . در ادامه بحث به یکی دیگه از فرمهای موجود در کیوتی خواهیم پرداخت که اونم Dialog ها هستند.

.:saeed:.
جمعه 08 بهمن 1389, 01:14 صبح
دیالوگ ها
از این لحظه وارد قسمت دیالوگ ها میشیم. دیالوگ ها فرم هایی هستند که برای ارتباط با کاربر در حین برنامه مورد استفاده قرار میگیرند . دیالوگ ها انواع مختلفی دارند و یا ممکنه جاهای مختلفی مورد استفاده قرار بگیرند. با توجه به اینکه کجا استفاده میشند باید ویژگی خاصی داشته باشند. مثلا در مورد یه فرم تنظیمات که باید با دیالوگ ها در کیوتی ساخته بشند تا زمانی که کاربر این دیالوگ را تایید نکنه نباید بشه به برنامه اصلی برگشت .اما مثلا در یه دیالوگ سرچ دیگه این قضیه صادق نیست همون طور که در برنامه هایی مثل اکسپلورر ها دیدین دیالوگ هم زمان با برنامه اصلی فعال هست ( راستی این که میگم دیالوگ و برنامه اصلی شاید تلقین بشه که برنامه ما و دیالوگ جدا از هم هستند که این طور نیست برای تمایز بینشون از این لفظ استفاده کردم وگرنه این دو در یک برنامه هستند ) با این حساب به دیالوگ با انواع مختلف نیاز مندیم :

دیالوگ های مدال Modal Dialogs
برخی از مواقع در برنامه ها دیدین که برنامه با رسیدن به بعضی از دیالوگ ها اصطلاحا بلاک میشه و تا زمانی که ارتباط کاربر با اون دیالوگ برقرار بقیه برنامه قابل دسترسی نیست .در این دیالوگ ها معمولا چیزایی قرار داده میشه که برنامه قبل از ادامه به کارش نیاز داره اونا رو بدونه . مثلا همین الان ctrl+o رو بزنید محاله بتونید تازمانیکه دیالوگ open باز هستش با قسمت های دیگه ارتباط برقرار کنید.به این دیالوگ ها Modal گفته میشه .

زمانی که شما یه شی از کلاسی که پایه اش QDialog باشه بسازید چیزی به شما نمایش داده نمیشه (درست مثل widget ها). با استفاده از تابع exec عضو کلاس QDialog شما در واقع دیالوگتون رو نمایانش میکنید یک . دوما یه event loop جدید برای اون دیالوگ ایجاد میکنید .بنابر این این شباهت اسم تابع گفته شده با تابع عضو کلاس QApplication کاملا قابل تفسیره . با اجرای این تابع دیالوگ شما نمایش داده میشه و در ضمن قسمت های دیگه برنامه هم بلاک میشه






QFileDialog dialog;
int status = dialog.exec();



مثلا کد بالا رو ببینید . قبلا QFileDialog رو دیده بودیم . با ساختن یه شی ازش و exec کردن اون دیالوگ ما نمایش داده میشه و در ضمن تا زمانی که از دیالوگ نمایش داده شده یا با استفاده از تابع accept و یا reject ( توضیح داده میشوند ) خارج نشیم تابع exec باز نخواهد گشت. یعنی دستورات بعد از این تابع ، بعد از اینکه دیالوگ بسته شد اجرا میشند.
خوب تابع exec با دو مقدار میتونه برگرده . یا قبول دیالوگ یا رد دیالوگ . فرضا ما میخواهیم یه سری تنظیمات رو اعمال کنیم اگه مقدار بازگشتی قبول بود اعمال کنیم و اگه رد بود اعمال نکنیم . این مقادیر با دو enum قابل تشخیص هستند . QDialog::Accept و QDialog::Reject . این دو در if قابل استفاده هستند.
در ضمن وقتی از QDialog ارث بردیم و داریم در این کلاس کد مینویسیم میتونیم با تابع accept عضو کلاس QDialog دیالوگمون رو با مقدار بازگشتی QDialog::Accept ببندیم و تابع reject() برای بستن دیالوگ با مقدار QDialog::Reject استفاده میشه.

.:saeed:.
جمعه 08 بهمن 1389, 01:36 صبح
دیالوگ هایی که مدال نیستند Non-Modal Dialogs
در تمام موارد هم نمیشه از Modal dialogs استفاده کرد . بعضی از مواقع کارایی دیگه ای مد نظر ماست .مثال خوبش دیالوگ های سرچ درون یه ویرایشگر متن هست . در این مواقع کاربر نیاز داره که همزمان با هر دو بخش برنامه یعنی هم document و هم دیالوگ سرچ بتونه ارتباط داشته باشه. در مواقعی که شما یه دیالوگ رو با هدف Non modal dialog پیاده سازی کردین باید از تابع show برای نمایش اون استفاده کنید . نکته بسیار مهم این است که تابع show بلافاصله برمیگرده و ارتباط شما با دیالوگ باید با استفاده از سیگنال ها اسلات ها انجام بشه. خوب یه نکته مهم دیگه اینکه : شما اگه توی یه تابعی نیاز به یه دیالوگ داشتین ، اگه non modal هستش شما حتما باید اونو با new ایجاد ش کنید در غیر این صورت با برگشت بلا فاصله show و خروج از تابعی که این شی رو توش ساختین ، دیالوگتون از بین میره اما اگه شما modal هستش میتونید اونو یا با New یا روی استک بگیرید.( چون تابع exec تا زمانیکه دیالوگ هستش بر نمیگرده ).

.:saeed:.
دوشنبه 11 بهمن 1389, 08:03 صبح
سلام دوستای عزیز صبح بخیر
در این قسمت قصد داریم دیالوگ های آماده در کیوتی رو بررسی کنیم . این دیالوگ ها در بسیاری از مواقع کار رو براتون خیلی راحت میکنند . قبلا دو نمونش رو دیدیم QFileDialog که برای ذخیره و باز کردن فایل استفاده میشد.

دیالوگ های پیغام
خیلی وقتا میخواید یه چیزی رو به اطلاع کاربر برسونید . خیلی وقتا نیاز دارین به کاربر بگین که درخواستش انجام شد . خیلی اوقات نیاز دارین از کاربر سوالاتی بپرسین . در این صورت شما نیاز به یه message boxپیدا کردین .برای این کار میتونید یه کلاس از کلاس QDialog به ارث ببرین و اونو همون طور که خودتون دلتون میخواد بسازینش و بعدش اونو exec کنید . اما خوب نیازی به این کار نیست چون کیوتی کلاس QMessageBox رو براتون در نظر گرفته. نکته ای که هست شما میتونید از این کلاس یه شی بسازین و به تناسب نیازتون اینکنشو ست کنید .یا دکمه براش اضافه کنید . متن اصلی شو تغییر بدین و از این کار ها . ولی یه راه راحتر هم وجود داره . توابعی از این کلاس موجودند که استاتیک هستند یعنی نیازی به شی برای فراخونی شون نیست . استفاده از این توابع در اکثر مواقع نیازتون رو مرتفع میکنه. این توابع عبارتند از:
QMeesageBox::question : برای پرسش یک سوال از کاربر استفاده میشه.

QMessageBox::information : برای رساندن یه پیغام خبری به کاربر استفاده میشه.

QMessageBox::warning :برای هشدار دادن به کاربر استفاده میشه.

QMessageBox::critical :برای پیام خطا دادن به کاربر استفاده میشه.




int respond= QMessageBox::question(this,
"Quit","Are you sure?",
QMessageBox::Yes|QMessageBox::Default,
QMessageBox::No|QMessageBox::Escape);
if respond != QMessageBox::Yes)
{
//do something
}
else
{
//do somethnig
}


خوب سوال پرسیدن رو با هم بررسی میکنیم . همون طور که میبینید تابع question با چند پارامتر صدازده میشه. پارامتر اول برای تعیین Parent این دیالوگ هست . پارامتر دوم تعیین caption یه جعبه متن همون عنوان بالای پنجره یه دیالوگ . پارامتر سوم برای تعیین متن اصلی و در واقع سوال پرسیده شده. برای تعیین دکمه ها هم از پارامترهای ارسالی بعدی استفاده میکنیم. لیست دکمه هایی که میتونید برای این تابع ارسال کنید در assistant موجود هست.
خوب این تابع یه دیالوگ سوال رو نمایش میده و دکمه ای که کاربر کلیک کرده رو برمیگردونه . پس بعد از اینکه کاربر یه دکمه ای از سوال پرسیده شده رو کلیک کرد مقدارش در respond قرار میگیره. چون دکمه در QMessageBox به صورت enum هستش میتونید مقدار بازگشتی رو توی یه متغیر از جنس int بریزید و بعد با QMessageBox::Yes تستش کنید . اگه برابر بود یه کاری انجام بده و اگه نه یه کار دیگه .
خوب انواع دیگه message box در ادامه بحث خواهد شد.
خسته نباشید.

.:saeed:.
پنج شنبه 14 بهمن 1389, 19:17 عصر
سلام خدمت دوستای عزیز .
تا اینجا چند تا دیالوگ استاندارد رو با هم دیدم .

خوب دیالوگ های هشدار و پیام و اخطار شبیه به هم هستند و ما فقط یکشونو بررسی میکنیم.
گفتیم برای رساندن یه خبر از information استفاده میکنیم



QMessageBox::information( 0, "Connecting to database", "Connection stablished." );


مثل دیالوگ قبلی ، پارامتر اول پدر ( اینجا پدر نداریم) و پارامتر دوم عنوان جعبه پیام و پارامتر سوم پیام مورد نظر. در حالت پیش فرض دکمه ok برای دیالوگ در نظر گرفته میشه ولی مثل مثال قبلی میتونید دکمه موردنظرتون رو اضافه کنید.

.:saeed:.
پنج شنبه 14 بهمن 1389, 20:12 عصر
دیالوگ های استاندارد : پیام های خطایی که یک بار نمایش داده میشوند

در برنامه های استاندارد زیاد دیدن مواقعی که یه پیام بهتون نمایش داده میشه و پیام حاوی یه تیکیه که اجازه میده دیگه این پیام نمایش داده نشه. مثلا تیک حاوی متن Don't show this message again رو خیلی دیدین . آیا این کار در کیوتی امکان داره بله. با کلاس QErrorMessage.

بر خلاف کلاس QMessageBox که شما بدون هیچ شیی و به صورت استاتیک میتونستید یه پیام نشون بدین ولی اینجا دیگه اینطور نیست . اشیای این کلاس وقتی که شما اسلات showMessage عضو کلاسشون یعنی QErrorMessage رو صدا بزنید ( چه مستقیم چه با سیگنال ) پیام رو نشون میدن.

اشیای این کلاس دو خاصیت دارند . به کد زیر نگاه کنید تا توضیح بدم



QErrorMessage *msg= new QErrorMessage;
msg->showMessage("Error1");
msg->showMessage("Error2");
msg->showMessage("Error1");
msg->showMessage("Error2");


اولا این که تا پیام اول در حال نمایش هستش پیام های دیگه نمایش داده نمیشند . در ثانی اگه Error1 تیکش برداشته بشه دیگه Error1 دومی نمایش داده نمیشه

ghasem.fattahpour
دوشنبه 26 اردیبهشت 1390, 16:47 عصر
آقا سعید چرا ادامه نمیدی؟ خیلی خوب بود.

.:saeed:.
سه شنبه 27 اردیبهشت 1390, 18:49 عصر
آقا سعید چرا ادامه نمیدی؟ خیلی خوب بود.

ممنون . شرمنده ، سرم شدیدا شلوغه :ناراحت:. در اولین فرصت به روی چشم

Hossenbor
شنبه 11 تیر 1390, 08:25 صبح
سلام خدمت دوستان عزیز اینو پیدا کردم دلم نیومدم که واسه شما نزارم http://www.qtrac.eu/C++-GUI-Programming-with-Qt-4-1st-ed.zip
در ضمن یکی از استادا گفت دلم نمیاد پست بزنم منم در جوابش میگم اگه ما اوپن سورسیا هوای همو داشته نباشیم هیچکس هوامونو نداره

hamidiatiye89
جمعه 04 شهریور 1390, 20:53 عصر
سلام من تازه با کیوت اشنا شدم و خیلی باهاش کلنجار رفتم وازش لذت بردم از اموزشاتون خیلی ممنون ولی من که تازه کارم خیلی کم ازش فهمیدم .هدف من نوشتن یه برنامه هست که به گوشه همه خورده مدیریت یک کتابخانه به صورت ساده میخواستم بدونم از کدوم قسمت کیوت بیشتر باید استفاده کنم ومهارت بیشتری داشته باشم تا بتونم پروژه ام را هرچه زودتر انجام بدم اگر هر راهنمایی که میتونید بکنید ممنون

arash_eetemad
شنبه 05 شهریور 1390, 03:07 صبح
با سلام
شرمنده از اینکه دیر شد.
چون دیدم از مقدمه سی پلاس پلاس زیاد استقبال نشد گفتم حتما دوستان در این مورد مشکلی ندارند . خوب اونو skip کردم و رفتم سر اصل مطلب . قسمت بعدی مقدماتی از کیوتی و محیط ها و نرم افزارهای همراه کیوتی به صورت کلی معرفی شدند . بررسی و آموزش هر کدام ، ان شاءالله در ادامه مباحث خواهد آمد
دانلود (http://www.4shared.com/file/SGWRPkTK/Qt3.html)قسمت سوم از آموزش کیوتی ( مقدمات و محیط های همراه )
موفق باشید.
خیلی قشنگ پیش رفته بودید. حیف شد که skip کردید. من کتاب آقای دایتل رو خوندم تا آخر کلاس ها اما شما خیلی قشنگ ترجمه کرده بودید ای کاش به همان سیاق ادامه می‎دادید. برای ما کلاس اول های برنامه نویسی خیلی خوب بود به هر حال اگه ممکنه وسط این معرکه وقفه ای ایجاد کنید یا اینکه همزمان اون قسمت هم ادامه بدید.
با تشکر

.:saeed:.
شنبه 05 شهریور 1390, 10:15 صبح
سلام
خیلی ممنون از نظرتون . بله حتما ادامه خواهد داشت . شاید از این هفته و شاید از هفته بعد .

.:saeed:.
دوشنبه 07 شهریور 1390, 11:37 صبح
سلام در بخش بعدی برنامه نویسی کیوتی میریم سراغ مطالب یکم پیشرفته تر . از Event ها شروع میکنیم

Events رخدادها
رخدادها یا Event ها چه هستند ؟ سوال مهمی است . برای اینکه بیشتر بفهمیم که رخداد ها چه چیز هایی هستند اجازه بدید بیشتر در مورد اونا بدونیم. البته از دیدگاه ویندوزی !
ببینید برنامه های Consoleای که مینوشتیم راهی نداشتیم که با سیستم عامل ارتباط برقرار کنیم و به همین دلیل مثلا تابعی مثل scanf را برای گرفتن ورودی از کاربر صدا میزدیم. ولی در دنیای سیستم عامل های جدید این طور نیست. شما به واقعیت نزدیک تر میشوید . به چه صورت ؟ بذارید یه مثال بزنم . بچه ها رو دیدید که توی یه مسافرت طولانی آدم رو کلافه میکنن که رسیدیم ، رسیدیم؟ رسیدیم ؟ پس کی میرسیم؟ رسیدیم؟
وای آدم کلافه میشه و با صدای بلند میگیم نه عزیزم وقتی رسیدیم بهت میگم. صدا زدن تابعی مثل scanf مثل بچه ای میبینه که مرتب بگه رسیدیم، رسیدیم؟ بله شاید کاربر ساعت ها دلش نخواد یه مقدار برای برنامه ما ارسال کنه و تابع منتظر ورودی است. ولی در سیستم عامل ویندوز رویه یکمی فرق داره . ویندوز به شما میگه این قدر نگو ورودی ورودی ، هر وقت اومد بهت خبر میدم ! بله ویندوز هر وقت که خبری بشه بهتون پیام میده و خبرتون میکنه از یه واقعه (Event) .
پس یه خبرایی داره میشه ! ویندوز میخواد با شما ارتباط برقرار کنه و این ارتباط از طریق پیام هایی است که برای شما میفرسته . بذارید یکم بیشتر بدونیم . یعنی چی پیام میده به ما ؟ سوال خیلی خوبیه .
در برنامه های ویندوزی ما در برنامه مون یه تابعی به نام Window Procedure باید تعریف کنیم که شاهراه ارتباطی ما با ویندوزه. هر وقت ویندوز دلش خواست به ما پیام بده این تابع رو صدا میزنه و یه خبری به ما میده . مثلا میگه که کلید فلان زده شد. یا ماوس روی فلان نقطه شما زده شد . یامیگه که باباجون ! یه پنجره اومد روی شما و رفت کنار باید خودتو دوباره طراحی کنی ! از این پیاما میده . خوب برنامه ای که توی کیوتی ( شونصد بار دیگه هم که بگین کیوت درست تر تره ما با کیوتی بیشتر حال میکنی ام ) مینویسین ( البته توی ویندوز ) به همین صورته . یعنی ویندوز برای شما پیام میده . ای بابا دروغ نگو من که تا حالا از ویندوز پیامی دریافت نکردم !
درسته ! اصن کیوتی اومده همین کارو بکنه . چکار ؟ بعضی از چیزا رو از دید شما مخفی کنه و یه راه راحتتر براتون ایجاد کنه . مثلا یکیش همین پردازش رخداد ها ( پیام ها ) است. زمانیکه ویندوز پیام میده براتون کیوتی یکم ملایم تر ! خبرتون میکنه تا هر کاری که میخواید بکنید.
بذارید بحث رو باحال ترش کنیم ! سیگنال ها به نظرتون چی هستند ؟ اونا هیچی نیستند جز پیام ها که به شیوه خاصی اعلان میشند! یعنی چی ؟ ببینید قرار شد وقتی روی منِ دکمه کلیک شد ویندوز با پیامی من رو خبر کنه . خب من ِ دکمه هم شما رو با سیگنالی خبر میکنم. پس بذارید جمع بندی کنم : برخی از پیام های مهم به صورت سیگنال در اختیار ما قرار داده میشند تا راحتر تر باشیم . و برخی هم اگه قراره باهاشون کاری کنیم باید بریم سراغ بحث پردازش پیام ها ( رخداد) (Event Processing) .حالا یه سوال؟ میشه من از سیگنال یه پیام استفاده نکنم و بجاش از پیام به صورت مستقیم استفاده کنم؟ سوال خوبی بود . به صورت مستقیم مستقیم که نه . ولی میتونید از راه یکم مستقیم تر به نام پردازش رخداد ها استفاده کنید. مثلا میدونیم که دکمه سینگال clicked داره . در عین حال ما میتونیم رخداد کلیک شدن روی یه دکمه را خودمون تعریف کنیم که چه اتفاقی در جواب اون رخداد بیفته.
پس به اینجا رسیدیم که در ویندوز وقتی کاربر یه کاری کرد، ویندوز از طریق پیام به ما خبر میده. ما هم شاید بخواهیم در جواب اون پیام یه کاری انجام بدیم . انجام اینکارا توی کیوتی Event Handling یا Event Processing نام داره. مثلا تاحالا شده از خودتون بپرسید که چطور میشه مثلا وقتی روی یه ویدجت خالی کلیک میشه یه اتفاقی بیفته ؟ نپرسیدین ؟ واقعا ؟
قانون زیر رو حیفم اومد ترجمه کنم : As a rule, signals are useful when using a widget, whereas events are useful when implementing a widget.برای مثال وقتی داریم از دکمه استفاده میکنیم راحت تر هستیم که از سیگنال استفاده کنیم تا اینکه خودمون رو درگیر پیامهای ماوس کنیم.
زمانیکه اتفاقی می افته برای یه ویدجت که ویندوز براش پیام میفرسته مثلا فرض کنیم روی یه ویدجت کلیک میشه ، کارایی که قراره در جواب اون اتفاق انجام بشه توی یه تابعی قرار میگیره که با کلمه Event تموم میشه . مثلا چی ؟ فرض کنید روی ویدجت ما کلیک میشه در اینجا ما تابعی خواهیم داشت به نام mousePressEvent که هر دستوری داخلش بنویسیم برای ما اجرا میشه( البته هر مرتبه که روی ویدجت ما کلیک شد. ) این تابعها کجا بودند ؟ این تابع ها به صورت مجازی (virtual) در کلاس QWidget قرار دارند و ما با باز تعریف آنها (Re Implement) باعث میشیم که تابع ما به جای تابع اصلی صدا زده بشه. برخی مواقع هم تابعی که توی کلاس هستش کاری انجام نمیده . مثلا mousePressEvent داخل QWidget هیچ کاری انجام نمیده. از کجا فهمیدیم؟ از اینجا که با کلیک کردن روی یه ویدجت هیچ اتفاقی نمی افته. ولی اگه من بیام و این تابع رو باز تعریف کنم و توش یه دستوری بنویسم ، از این به بعد هر بار که من روی ویدجتم کلیک میکنم یه اتفاقی خواهد افتاد.
بذارید یه مثال ساده بزنیم. یه کلاس به برنامه تون اضافه کنید که از QWidget ارث برده باشه. حالا به فایل header خط زیر را اضافه کنید:

protected:
void mousePressEvent(QMouseEvent *);


void Widget::mousePressEvent(QMouseEvent *)
{
QMessageBox::information( this, "Clicked", "I'm clicked!");
}

حالا اون رو به صورت زیر تعریف کنید :
حالا یه شی از این کلاس جدیدتون بسازید و با تابع show اونو نمایش بدین و بعد روی ویدجتتون کلیک کنید .
حالا به عنوان تمرین یه کلاس از کلاس QPushButton ارث ببرین و تابع mousePressEvent اونو خودتون باز تعریف کنید ببینید چی میشه و چطور میشه حلش کرد ؟ ( سوال مهمی بودا)
فعلا...

.:saeed:.
جمعه 11 شهریور 1390, 00:10 صبح
مدیریت پیام ها ( رخدادها ) Events - قسمت دوم
در این قسمت پیام paintEvent گفته خواهد شد که یکی از رخداد های مهم است . در ضمن در این قسمت یه لاین ادیتی خواهیم ساخت که یه تصویر روش میاد و با کلیک شدن اون تصویر ( ضربدر ) متن داخلش پاک خواهد شد . ( مثلا فیلترها توی Designer ) . چون این قسمت خیلی کد داشت و وضعیت کد نویسی در برنامه نویس خیلی خوب نیست به صورت pdf در آوردم
برای دانلود اینجا (http://www.4shared.com/file/Z2WqQYBF/paintevent.html)را کلیک کنید.

.:saeed:.
یک شنبه 13 شهریور 1390, 15:57 عصر
موضوع : Events in Qt Part C - Event Filtering
مثال عملی : یه ویدجت با سه لاین ادیت در داخل اون که فشردن کلید space در اونا باعث انتقال Focus به لاین ادیت بعدی میشه .

با سلام . فکر کنم کسی حوصله دانلود کردن نداره خوب همین جا میذارم راحت باشید.

یکی از ویژگی های بارز و مهم کیوتی اینه که شما میتونید یه شی از جنس [1] QObject رو مامور کنید پیام های یه QObject دیگه رو بگیره، حتی بدون اینکه اون کسی که پیام ها مالش بود متوجه بشه . بذارید توضیح بدم. فرض کنید شما می خواهید یه QLineEdit بسازید (منظورم اینه که ازش ارث ببرید و بعدش یه سری چیز بهش اضافه کنید) که وقتی روش کلیک شد یه کاری انجام بشه . همون طور که میدونید QLineEdit سیگنالی به نام clicked نداره بلکه برای انجام این کار باید mousePressEvent این QLineEdit جدیدمون رو باز نویسی کنیم.
ولی یه راه دیگه ای هم داریم. به پدر این لاین ادیت که مثلا یه QDialog هستش بگیم که اگه پیامی برای این لاین ادیت اومد خودت جواب بده ، این لاین ادیت بچه اس نمیتونه جواب بده ! به این عملیات میگیم Event Filtering . یعنی یه کسی بشه مسئول یکی دیگه . در این صورت تمام پیام های فرضا QLineEdit ما برای QDialog ما ارسال میشه . خوب یه مشکلی هست . به نظرتون چه مشکلی ؟
من ( منظور از من همون QDialog )که قصد نداشتم تمام پیام ها رو خودم بررسی کنم ، من فقط یه پیام رو میخواستم از QLineEdit پردازش کنم و بقیه رو بذارم بر عهده خودش . مثلا وقتی پیام[2] Paint برای من ارسال میشه که من نمیتونم لاین ادیت رو نقاشی کنم . خودش باید نقاشی کنه . پس چکار کنیم. خوب خیلی ساده است دیگه . من هرچی رو دوست دارم خودم(QDialog) پردازش میکنم و بقیه رو خودش (QLineEdit) پردازش کنه . خیلی خوب شد این طوری .
خوب بذارید یه مثال عملی انجام بدیم تا متوجه بشیم . آقا من میخوام یه سری QLineEdit روی QDialog ام داشته باشم که وقتی در یکی از QLineEdit ها کلید Space رو زدم Focus[3] به QLineEdit بعدی برسه . یه راه حل اینه که من کد زیر رو بنویسم


void MyLineEdit::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Space) {
focusNextChild();
} else {
QLineEdit::keyPressEvent(event);
}
}

یعنی بیام و پیام صفحه کلید ( پیام فشرده شدن یه کلید ) که همون keyPressEvent هست رو در مورد QLineEdit باز نویسی کنم و توش بنویسم اگه کلید space زده شد برو سراغ شی بعدی رو دیالوگ ما که باید input focus رو دریافت کنه اگه غیر این بود به کلاس پایه QLineEdit میگم آقا کار خودتو بکن . کار خودش چی بود هیچی این کلید فشرده شده رو پردازش کنه و اگه قرار کاراکتری نمایش داده بشه نمایش بده. اگه این خط رو نذارید دیگه لاین ادیت چیزی نمایش نمیده.
دوتام مشکل داره این کار . یکیش اینه که ما حوصله نداریم واسه این یه کارساده یه کلاس جدید تعریف کنیم. دوم اینکه حالا اگه قرار شد QComboBox هم توی این فرم قرار بگیره دیگه هیچی ! بازم باید یه کلاس جدید برای اون تعریف کنیم و همین کارا رو برای keyPressEvent اش انجام بدیم .
ولی این کار به راحتی با استفاده از event filtering قابل انجامه. خوب انجام این کار دو مرحل داره:
1. باید به شی ای که میخوایم پیام ها شو بدزدیم بگیم که ما قصد انجام این کارو داریم . این کار با استفاده از تابع installEventFilter قابل انجامه. پس پیام های A از این به بعد برای B ارسال میشه.
2. B باید پیام ها رو در تابع eventFilter پردازش کنه.
در ادامه یه مثال عملی از این موضوع خواهیم دید.
کلاسی از جنس QWidget به صورت زیر تعریف میکنیم :

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
class QLineEdit;
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
Q_OBJECT

public:
explicit Widget(QWidget *parent = 0);
~Widget();

private:
Ui::Widget *ui;
QLineEdit *_led_a, *_led_b, *_led_c;
protected:
bool eventFilter(QObject *, QEvent *);
};

#endif // WIDGET_H

همون طور که میبینید قصد داریم سه تا QLineEdit داشته باشیم رو فرممون.سازنده ما به صورت زیر خواهد بود:

Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QVBoxLayout *hlay = new QVBoxLayout( this );
_led_a = new QLineEdit;
_led_a->installEventFilter(this);
hlay->addWidget(_led_a);
_led_b = new QLineEdit;
_led_b->installEventFilter(this);
hlay->addWidget(_led_b);
_led_c = new QLineEdit;
_led_c->installEventFilter(this);
hlay->addWidget(_led_c);
}

همونطور که میبیند برای هر سه LineEdit مون با استفاده از تابع installEventFilter شی کلاس ای از جنس QWidget که همون widget (نام کلاس ارث برده شده ) رو مسئول پیام های این سه لاین ادیت قرار دادیم.

bool Widget::eventFilter(QObject *target, QEvent *event)
{
if (target == _led_a || target == _led_b
|| target == _led_c ) {
if (event->type() == QEvent::KeyPress) {
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Space) {
focusNextChild();
return true;
}
}
}
return QWidget::eventFilter(target, event);
}

برای تابع eventFilter رو مقدار ارسال خواهد شد. یکی اینکه پیام در اصل ماله کیه . دوم اصلا پیامه چیه ؟ ما اول میام و چک میکنیم که آیا پیام ارسالی مال یکی از QLineEdit هاست یا نه . و بعدش میام میبینم که آیا پیام ارسالی اصلا از جنس پیام صفحه کلیدی است یا نه . چون قرار شد همه پیام ها برای این تابع ارسال بشه. خوب پس پیام از جنس صفحه کلیدی یعنی از جنس شی ای از کلاس QKeyEvent ( کلاسی است که اطلاعات تکملی در مورد پیام صفحه کلید را دارد مثلا اینکه کدام کلید فشرده شده ) ولی پارامتر ارسالی از جنس QEvent هستش که پایه تمام کلاس های Event مث QMoseEvent و QKeyEvent هستش . همون قاعده چند ریختی دیگه . خوب با یه Cast ساده یه شی از جنس QKeyEvent به دست میاریم و بعدش میبینیم که آیا کلید فشرده شده space هست یا نه اگه هست که ما پیام را پردازش میکنیم و مقدار true برمیگردانیم که به کیوتی بگیم آقا ما این پیام رو پردازش کردیم .اگه ما مقدار false بر میگردوندیم کیوتی تصور میکرد که پیام پردازش نشده و به شی QLineEdit مربوطه میفرستادش پیام رو.
خوب اینم از این مثال و از این آموزش

پاورقی
[1]
منظور از یه شی از جنس QObject شی است که یا خودش از QObject ساخته شده باشد یا به صورت مستقیم یا غیر مستقیم از QObject به ارث برده شده باشد

[2]
دقیقا پیامی با نام WM_PAINT برای Window procedure ما ارسال میشه.
[3]
ببینید نکته ای که هست اینه : برنامه ها از یه سری Widget درست شدنددیگه مثلا دکمه و لاین ادیت و اینا . پیام های صفحه کلید در آن واحد فقط واسه یکی میشه فرستاده بشه . مثلا شما میتونید در یه لحظه واسه دوتا Note Pad تایپ کنید نمیشه که . حالا این ورودی های صفحه کلید ( پیام های صفحه کلید ) واسه کی فرستاده میشه ؟ واسه کسی که Input Focus داشته باشه . چه کسی Input Focus رو داره . مثلا در مورد LineEdit زمانی که Caret در داخلش چشمک میزنه یعنی Input Focus داره.

پیشنهاد : محض اطلاع خواستم بگم که IP Editor ویندوز رو تا حالا دیدین !

.:saeed:.
یک شنبه 13 شهریور 1390, 16:40 عصر
دانلود فایل pdf و فایل های پروژه این قسمت از اینجا (http://www.4shared.com/file/sFgU_KVe/EventFilter.html)

alamate_aoal
سه شنبه 29 شهریور 1390, 07:05 صبح
سلام خدمت دوستان عزیز اینو پیدا کردم دلم نیومدم که واسه شما نزارم http://www.qtrac.eu/C++-GUI-Programming-with-Qt-4-1st-ed.zip

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

gbg
یک شنبه 24 مهر 1390, 10:37 صبح
بعضی از فایل های 4shared.com دانلود نمیشه چون ف..ر شدن

X-DATA
چهارشنبه 17 خرداد 1391, 14:24 عصر
اگر فرصت شد همه آموزشی ها را به صورت یکجا توی یک فایل PDF قرار دهید ترجیحا روی mediafire - بزارید ممنون

omidshaman
پنج شنبه 27 مهر 1391, 10:01 صبح
برای یادگیری QT لازمه حتما c++ بلد باشم؟ یا اگر به c هم مسلط باشم میشه؟

alamate_aoal
پنج شنبه 04 آبان 1391, 08:25 صبح
http://qt-project.org/wiki/Category:LanguageBindings

MOJTABAATEFEH
پنج شنبه 04 آبان 1391, 08:42 صبح
دوست عزیز ممنون بابت کار قشنگتون اگر ممکنه لطفا یک اطلاعاتی به صورت فارسی راجع به این زبان و مزایا و معایبش بدین

با تشکر

rubiks.kde
جمعه 05 آبان 1391, 19:42 عصر
Qt یک چهارچوب توسعه نرم افزار میان سکویی (Cross Platform ) که معمولا برای توسعه نرم افزارهای واسط گرافیکی ( GUI ) استفاده می شود. Qt بسیار کاملتر از مجموعه ابزارهای دیگر مانند GTK است که تنها مجموعه ای از اشیای گرافیکی قابل استفاده بر روی پنجره ها هستند. Qt از زبان سی پلاس پلاس استفاده می کند ولی تبدیل آن بر روی اکثر
زبان های برنامه نویسی تولید شده است. همچنین اکثر ویژگیهای کیوت از Preprocessor موجود در زبان سی استفاده می کنند و برخی از ویژگیهای خاص آن ( مانند پنجره ساز و چندزبانی ) از یک پیش پردازنده که مخصوص خود کیوت است و کد آنرا به کد سی تبدیل می کند، استفاده می کنند.

مانند اکثر چهارچوب های برنامه نویسی واسط گرافیکی ( از جمله , Microsoft Visual Studio Apple Xcode , ... ) برنامه کیوت از یک حلقه رخداد اصلی ( Main Event Loop ) استفاده می کند. به دلیل متن باز بودن کیوت و رشد آن در طی سالهای اخیر، این حلقه بسیار بهینه پیاد ه سازی شده و از مشابه خود در سیستم های مذکور بسیار بهتر عمل می کند. مانند اکثر محیط های برنامه سازی گرافیکی، کیوت نیز از برنامه نویسی رخداد محور ( Event-Driven Programming ) پشتیبانی می کنند ولی الگوی مشاهدگر ( Observer Pattern ) که یکی از الگوهای بسیار عالی و موفق در مهندسی نرم افزار است امکانات و افق های بسیاری را به روی برنامه نویس می گشاید.

alamate_aoal
جمعه 05 آبان 1391, 23:29 عصر
دوست عزیز ممنون بابت کار قشنگتون اگر ممکنه لطفا یک اطلاعاتی به صورت فارسی راجع به این زبان و مزایا و معایبش بدین

با تشکر
منظورتون از زبان Qt که نیست؟

Bardia1984
پنج شنبه 02 شهریور 1396, 01:19 صبح
هیچ فایلی نیست