آموزش برنامه‌نویسی با کیوت / سی‌+‌+ (جلسه پنجم)

در جلسهٔ قبل این آموزش پروژهٔ کوچکی را با نام کیوت‌پد «CutePad» آغاز کردیم که یک نرم‌افزار ساده برای ویرایش متون و پرونده‌های متنی بود، این پروژه فعلاً کار خاصی انجام نمی‌دهد، فقط یک پنجره با ظاهری ساده را برای پروژهٔ کیوت خود توسط سی-میک ایجاد کردیم تا پروژه را برای ادامه کار شروع کرده باشیم. برای استفاده از کدهای این نوشته توصیه می‌:نم که در ابتدا کد منبع پروژه در جلسهٔ قبل را از طریق گیت‌هاب دریافت و بارگیری  کنید، اگر هم از قسمت قبل این پروژه را دریافت کرده‌اید نیز آن مجدداً بگشایید تا بتوانید از آن استفاده کنید. گفتنی است اگر از طریق گیت‌هاب می‌خواهید کدها را بارگیری کنید، بهتر است مشخص کنید که اولین  ارسال یا «Commit» را دریافت کنید  و  یا اینکه تغییراتی را که در این جلسه اعمال کردیم را نیز دریافت کنید. همچنین برای رفع این موضوع کمی اینترنت را جستجو کنید به پاسخ سوال می‌رسید. با این حال پرونده‌ٔ فشرده و آرشیوی از کد جلسهٔ قبل را می‌توانید ازاین پیوند دریافت کنید.

در این جلسه قصد دارم چند کد جدید را نیز آموزش دهم، مانند شیوهٔ کار با پرونده‌ها در کیوت که بسیار ساده است. در سی++ روش خاصی برای کار با پرونده وجود دارد، امّا در این جا از روش مخصوص کیوت استفاده خواهیم کرد. در این قسمت کدهای دیگر مربوط به خروج از پنجره و برنامه را نیز خواهیم نوشت. همچنین در آخر یک پروندهٔ میانبر برای نرم‌افزار می‌نویسیم که با قرار دادن آن در پوشه نرم‌افزارهای کاربردی در توزیع خود می‌توانید به آن از طریق فهرست نرم‌افزارهای میزکار خود دسترسی داشته باشید. این کار را زمانی انجام می‌دهیم که نرم‌افزار به صورت کامل نوشته شود. زمانی که این پروژه را به صورت کامل نوشتیم، می‌توانیم نرم‌افزار جدیدی را توسعه دهیم. در آخرین جلسات به آموزش ساخت یک نرم‌افزار برای سیستم‌عامل اندروید و نحوهٔ اجرا و تنظیم آن خواهیم پرداخت. برخلاف اکثر مطالب آموزش برنامه‌نویسی اندروید که از جاوا و سیستم‌عامل‌های دیگری چون ویندوز و اواس ده استفاده می‌کنند، آموزش برنامه‌نویسی در اندروید را با استفاده از گنو/لینوکس انجام داده و مراحل نصب شبیه‌ساز غیر متن‌باز و غیر رایگاه ولی رایگاه برای استفادهٔ شخصی  «Gemymotion» و استفاده از آن در کیوت را نیز آموزش خواهیم داد زیرا که SDK خود اندروید در گنو/لینوکس کندتر است. (نمایی از یک بازی ساده نوشته شده توسط کیوت اجرا شده در جمی‌موشن و اندروید ۵/۱ را مشاهده می‌کنید.)

qt-02

مقدمات و برخی توضیحات

در ابتدا از برخی مبانی کار می‌گوییم تا به قسمت نوشتن کدهای نرم‌افزار کیوت-پد برسیم. تمامی این موارد به کلاسهایی اختصاص دارد که در این مثال و این جلسه استفاده می‌شوند. این مسائل برای این در ابتدا گفته می‌شوند که در هنگامی که کدها را مشاهده می‌کنید، مشکلی نداشته باشید، با این حال همانطور که در قسمت اول و جلسه‌ٔ مقدمه ذکر کردم،  باید به زبان سی++ مسلط باشید و اگر نه نمی‌توانید درک درستی از کدهای زیر داشته باشید. کدهایی که از کلاس‌های کیوت استفاده می‌کنند را توضیح می‌دهم ولی قصد ما از این مطلب آشنایی شما با نحوهٔ نوشتن کد در کیوت و یا مدیریت پروژه، اجرا و استفاده از کلاس‌ها است و نه آموزش زبان سی++ از پایه.

QFile:

این کلاس برای گشودن یک پرونده به‌کار می‌رود و در این پروژه قصد داریم از آن استفاده کنیم تا پرونده‌های متنی را بگشاییم. این کلاس تنها به آدرس پرونده نیاز دارد تا بتواند آن را برای ما نمایش دهد. بعد از آن که این کلاس تعریف شد، باید آن را به QTextStream نسبت دهیم، البته در این موقع باید قبل نام کلاس یک & بنویسیم.

QTextStream:

از این کلاس قبلاً استفاده کرده‌ایم، این کلاس برای ایجاد یک جریان متنی کاربرد دارد، این جریان متنی را می‌توان به طرف خروجی هدایت کرد یا به یک پرونده.  گفتنی است اگر با استفاده از ین کلاس و کلاس قبلی پروندهٔ dev/random/ را بگشایید، مقداری متن تصادفی تولید خواهد شد که برای برخی کاربردها بسیار مناسب است.

QFileDialog:

همانطور که از نامش پیداست برای گشودن برخی کادرهای محاوره‌ای که مرتبط با گشودن و ذخیرهٔ پرونده هستند، استفاده می‌شود. اگر می‌خواهید دیگر کادرهای محاوره‌ای را باز کنید، کلاس مخصوص به خود را دارند که در جلسهٔ بعد توضیح خواهم داد.

QFileInfo:

برای نمایش برخی اطلاعات از پرونده‌ها به کار می‌رود، مثلاً نام پرونده چیست یا برخی اطلاعات دیگر مانند تاریخ و … .  در این پروژه از این کلاس استفاده کرده‌ایم تا نام پرونده را بدون در نظر گرفتن آدرسش در نوار عنوان نمایش دهیم. همچون برخی ویرایشگرهای متن مرسوم که نام پرونده را در نوار عنوان به نمایش می‌گزارند.

مثالی ساده:

به مثال زیر اگر توجه کنید، در آن از کلاس QFile استفاده شده است، در این مثال پرونده‌ای گشوده می‌شود، مقادیری در آن ذخیره شده و سپس برنامه بسته می‌شود.

در داخل متغیر myfile باید آدرس دقیق پرونده را وارد کنید. سپس اگر وارد پروندهٔ فوق شوید مقادیری که در زیر نوشته شده را در آن مشاهده خواهید کرد.

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

کد بالا کد ساده‌ای بود، متن زیر را که به زبان مجارستانی است را می‌خواهیم به صورت UTF-8 باز کنیم. UTF-8 را برای خط و زبان‌های غیر لاتین و انگلیسی به کار می‌برند.

کدهایی که برای گشودن این متن استفاده می‌شود همانند کد قبلی است، با این تفوات که در زمان ساخت جریان متنی «QTextStream» باید مشخص شود که متن باید به چه شکلی گشوده یا ذخیره شود.

حال بیایید نرم‌افزاری بنویسیم که بتواند همانند دستور «cat» ، خودش متن پرونده‌ای که نام و آدرسش در مقابلش نوشته شده را باز کند و در خروجی نمایش دهد. برای این‌کار باید از پارامترهایی که در برنامه هستند استفاده کنیم. ابتدا پوشه‌ای با نام دلخواه ایجاد کنید، سپس در داخل آن پرونده‌ای با نام «kat.cpp» یا هرچه که دوست دارید ساخته و در آن کدهای زیر را وارد کنید. (بهتر است نام پوشه را نیز kat بگزارید)

در دستورات بالا از از پارامترهای داخل تابع اصلی برای شناسایی مقادیری که بعد از نام دستور می‌آید استفاده کرده‌ایم. argc در این‌جا تعداد عبارات نوشته شده بعد از برنامه را مشخص می‌کند و argv آرایه‌ای است که مقادیر را نگاه می دارد. خانهٔ شمارهٔ ۰ این آرایه را نام نرم‌افزار و مابقی را عبارات و پارامترها پر می‌کنند. ما در این جا به یک عبارت نیاز داریم و فقط از شمارهٔ یک استفاده کرده‌ام.

حال با استفاده از دستورات زیر نرم‌افزار را کامپایل کنید، وارد پوشهٔ پروژه شده و داخل آن دستورات زیر را برای ساخت پرونده‌های مورد نیاز برای پروژه وارد کنید. سپس با استفاده از دستور make آن را کامپایل خواهیم کرد.

حال که نرم‌افزار کامپایل شده است اگر نام پوشه شما هر چه باشد، مثلا kat نام پروندهٔ اجرایی نیز به همین نام خواهد بود. آن را با دستور زیر به این شکل اجرا کنید، محتویات پروندهٔ تنظیمات پروژه را نمایش خواهد داد.

اگر این کد را نوشته‌اید، توانسته‌اید یکی از دتورات گنو/لینوکس را تنها با ۲۲ خط دستور سی++ و کیوت بنویسید. در داخل نرم‌افزاری که می‌نویسیم نیز از چنین قابلیتی استفاده خواهیم کرد تا در هنگام نوشتن عبارتی بعد از نام برنامه، بتوانیم آن را بگشاییم.


نوشتن کدهای برنامه

ابتدا، پروژه را باید با استفاده از دستور زیر از پایگاه اینترنتی گیت‌هاب دریافت کنید، سپس با استفاده از محیط توسعه کیوت، آن را بگشاید. برای گشودن آن پرونده تنظیمات سی-میک را باید انتخاب کنید.

حال که پروژهٔ کیوت‌پد بارگیری شده است و برای استفاده آماده است آن را می‌گشاییم. بعد از گشودن آن مجددا در سمت چپ فهرستی از پرونده‌های مورد نظر که به صورت جداگانه در پوشه‌های سرآیند و منبع قرار دارند را مشاهده می‌کنید. برخی از تغییرات را داخل کلاس «Actions» انجام می‌دهیم. ابتدا پروندهٔ سرآیند آن را باز کنید و در آن دستورات زیر را جایگزین دستورات قبلی کنید.

سپس باید در داخل، پروندهٔ منبع کلاس «Actions»، توابعی را که مشخص کرده‌ایم را تعریف کنیم، برای تعریف آن پروندهٔ منبع را باز کنید و در آن کدها و دستورات زیر را وارد کنید. در این مرحله فعلاً کد مربوط به گشودن و پروندهٔ جدید را می‌نویسیم.

کدها و خطوط زیر را نیز در داخل پروندهٔ منبع پنجره اصلی یعنی پروندهٔ «main_win.cpp» بنویسید. در این‌جا کدهایی را برای فراخوانی تابع بالا لازم است را می‌نویسیم.  کدهای زیر از کدهای جلسهٔ قبلی نیز تشکیل شده است، در ادامهٔ نوشته کدهای جدید را بیشتر توضیح خواهم داد.

پروندهٔ سرآیند کلاس پنجرهٔ اصلی را نیز با مقادیر زیر مجدداً پر کنید و مقادیر قبلی را پاک کنید، یعنی مقادیر زیر را جایگزین مقادیر قبلی کنید. در این پرونده برخی تغییرات کوچک اعمال شده و یا برخی ایرادها و موارد اضافی که وجود داشت از  کدهای فعلی نسبت به کدهای قبلی حذف و رفع شده‌اند.

حال برای عمل ایجاد پروندهٔ جدید کدها آماده است، کدهایی که برای ایجاد پنجرهٔ جدید برای این گزینه نوشته شده‌اند، کدهای زیر هستند. در این کد ما یک تابع تعریف کرده‌ایم و آن را در قسمت «private_slot» قرار دادیم. اگر تعریف تابع در داخل این قسمت نباشد، دستور «connect» با خطا مواجه می‌شود. همواره هر تابع اسلات «Slot» را در آن بخش از سرآیند تعریف کنید.

همانطور که مشاهده می‌کنید کدی که در بالا برای ایجاد پنجرهٔ جدید نوشته‌ایم، خیلی ابتدایی است و تنها متنی که  داخل کادر متنی قرار دارد را پاک می‌کند،  با این وجود به همین کد  در این جلسه کفایت می‌کنیم و در قسمت‌های آینده آن را توسعه خواهیم داد. امّا کدی که برای دکمهٔ گشودن نوشته‌ایم را تقریبا کامل کرده‌ایم. این کد در دو بخش نوشته شده است. ابتدا کادر گشودن پرونده و دیگر تنظیمات مورد نیاز را در یک تابع نوشته و در تابع دیگر فرآیند گشودن پرونده و متن پرونده را به صورت کامل نوشته‌ایم. کد تابع اول که برای رویداد کلیک گزینهٔ گشودن در نوار ابزار است، شامل کدهای زیر می‌شود. در این قسمت کدک پرونده را «utf-8» قرار می‌دهیم که توسط متغیری که آِن را در تابع به عنوان پارامتر تعریف کرده‌ایم، تنظیم خواهد شد.

با این وجود اگر تابع را به صورت دیگری فراخوانی کنیم، کُدک «Encoding» پرونده تغییر خواهد یافت که البته در این قسمت نیاز به تغییر کد نداریم و فقط هنگام فراخوانی تابع باید، متن «utf-8» را به متن دیگری تغییر دهیم.

در این کد ما از کلاس «QFileDialog» استفاده کرده و با آن توانستیم بفهمیم که شاخه خانگی کاربر جاری چه شاخه‌ای است. سپس آن را به شاخهٔ پیش‌فرض کلاس «QFileDialog» نسبت دادیم تا برای اولین بار در همان شاخه گشوده شود. قسمتی را برای مشخص کردن اینکه پرونده فقط خواندنی است یا نه مشخص کرده‌ایم، در صورت فقط خواندنی بودن پرونده گشوده شده، قابلیت ذخیره را غیر فعال خواهیم کرد که فعلاً به یک پیام ساده توسط «qDebug» بسنده کرده‌ایم. در داخل کلاس «QFiileDialog» همانطور که مشخص است، تابع اجرای کادری را که برای گشودن پرونده است نوشته و در آن نوع قالب‌ها مشخص شده‌اند. در آخر گفتیم اگر آدرس پرونده با مقدار  رشتهٔ تهی”” مساوی نبود و پرونده نیز وجود داشت، آدرس پرونده را به تابع بعدی که برای بیرون کشیدن داده‌ها است ارجاه داده و آن تابع را فراخوانی کند، بعد از آن خروجی تابع دوم را دریافت می‌کند و از طریق کادر متنی به نمایش در می‌آورد. کد تابع دوم نیز به شکل زیر است.

در این کد ما از یک تابع جدید استفاده کرده‌ایم که «QFile» نام دارد، (توضیحات مرتبط را در ابتدای مقاله مطالعه کنید)  در این کد، این تابع را تعریف کرده‌ایم، سپس آدرسی را به آن نسبت داده تا بتواند این پرونده را بگشاییم.

در کد بالا روش تعریف این کلاس را مشاهده می‌کنید، همان‌طور که ملاحظه می‌کنید، کدی که برای نوشتن آن به کار رفته است بسیار آسان است، بعد از آن باید یک جریان متنی ایجاد کنیم،  QFile را برایش تعریف کرده و از آن استفاده کنید تا بتوانید جریان متنی را از سوی پرونده به سمت یک متغیر رشته‌ای ایجاد کنید.

در آخر نیز پرونده را بسته و همه چیز را پاک میکنیم. معمولا وقتی پرونده‌ای گشوده می‌شود، فضایی از حافظه داخلی و جانبی درگیر می شوند که با این دستورات که در زیر می‌آید، آنان آزاد خواهند شد. در هر بار گشودن پرونده این کار را انجام دهید، در سی++ نیز پرونده‌ها را بعد از گشودن می‌بندند در کیوت هم باید چنین کرد.

در آخر اطلاعات خوانده شده را در تابع به خروجی باز می‌گرداند، تا در صورتی که تابع فراخوانی شد به عنوان خروجی، اطلاعات داخل متن را در یک متغیر رشته‌ای برگرداند. به این شکل ما تابعی نوشته‌ایم که در آن تابع برخی کدها قرار دارد، بخش اصلی کد را به یک تابع سپرده‌ایم که کارهایی را انجام می‌دهد و سپس خروجی را مجدداً به آن یکی تابع می‌دهد که کارش را ادامه دهد.


پایان جلسهٔ پنجم

تقریباً این قسمت را به دلیل این‌که مباحث مطرح  شده از این سنگین‌تر نشود، تمام می‌کنم. کدهایی که در این جلسه نوشته شده‌اند را نیز می‌توانید از طریق گیت‌هاب دریافت کنید. برای بارگیری آن از طریق خط فرمان دستور زیر را در پوشه‌های دلخواه اجرا کنید تا پروژه مجدداً بارگیری شود، اگر پروژه را از قبل داشتید نیز مقادیر جدید را دریافت کنید. گیت‌هاب بهترین مکانی است که می‌توانم کدها را در آن به اشتراک بگزارم به دلیل این‌که این پروژه یک پروژهٔ دنباله‌دار و ادامه دار است و در هر قسمت کامل می‌شود، برای راحتی کار خودم و شما از گیت و گیت‌هاب استفاده کرده‌ام. با این حال در هر جلسه پروندهٔ فشرده‌ای از کدهای جلسهٔ قبل را نیز برای کسانی که کدهای جلسهٔ قبل را ندارند، قرار خواهم داد.

در آخر ظاهر نرم‌افزار به شکل زیر خواهد بود. همانطور که مشخص است از توزیع کی‌دی‌ای استفاده می‌کنم، با این وجود اگر این کدها را در گنوم یا حتی سیستم‌عامل دیگری نیز اجرا کنید، نتیجهٔ مشابهی را مشاهده خواهید کرد به غیر از اینکه نقشک‌ها و ظاهر نرم‌افزار شما به ظاهر سیستم‌عامل و میزکار خودتان نزدیک‌تر خواهد بود.

qt-01

نرم‌افزار بعد از کامپایل تغییر خاصی از نظر ظاهری  با جلسهٔ چهارم یا قبل نداشته است، فقط گزینه‌های جدید «New» و گشودن «Open» در نوار ابزار و منو می‌توانند کارهایی را انجام دهند، مثلاً متونی را که در کادر متنی قرار دارند را پاک کنند یا اینکه پرونده‌ای را با استفاده از پنجره و کادر محاوره‌ای گشودن پرونده، باز کرده و نمایش دهد. به صورت پیش‌فرض فعلاً از UTF-8 استفاده می‌شود در آینده از یک گزینهٔ جدید استفاده می‌کنیم تا مشخص کنیم که همواره پرونده‌ها در چه حالتی گشوده و نمایش داده شود. مثلاً اگر گزینهٔ عربی در ویندوز را انتخاب کنید، می‌توانید برخی زیرنویس‌هایی که در این حالت ذخیره شده‌اند را گشوده و با UTF-8 مجدداً ذخیره کنید، البته نرم‌افزاری جداگانه با استفاده از کیوت و کیو-میک نوشته‌ام، که در آینده‌ای نزدیک با انتقال  کامل پروژه از کیو-میک به  سی-میک، آموزش این پروژهرا  نیز شاید در جلسه‌ای خواهیم نوشت و نرم‌افزار مذکور را با هم ارتقاء خواهیم داد.

اگر پیشنهادی دارید که می‌تواند در جلسهٔ بعدی به کار گیریم یا اینکه برای پروژه و نرم‌افزار بعد از اتمام این پروژه و  نرم‌افزار پیشنهادی دارید،  پیشنهاد خود را با ما در میان بگزارید. همچنین اگر در مورد نرم‌افزاری که برای اندروید خواهیم نوشت نیز نظری دارید، آن را  مطرح کنید تا موضوع نرم‌افزاری که برای اندروید می‌نویسیم از پیش مشخص باشد.

5 دیدگاه در “آموزش برنامه‌نویسی با کیوت / سی‌+‌+ (جلسه پنجم)

  1. سلام آقا احسان

    دانشجوی مهندسی کامپیوتر هستم . متاسفانه توی تمام درسها سی شارپ به خرد ما میدن الان مدت کوتاهیه با کیوت کار میکنم .
    2تا مشکل با qt دارم :

    1-ساخت فایل نصب (install) که بعد از کلی گشتن تو اینترنت با https://doc.qt.io/qtinstallerframework/index.html اشنا شدم اما روش کار باهاش را نفهمیدم.
    2-برنامه ای که با کیوت تحت ویندوز کامپایل شده توی کامپوترهای دیگه ارورر ( ویژوال سی ++ ران تایم ) میده با اینکه dll ها و فایلهای داخل پوشه Qt\Qt5.5.0\5.5\mingw492_32\plugins\platforms
    را هم کنار برنامه کوپی کردم . اما بازم نشد .

    راه ارتباط با شما چیه؟؟

    لطفا راهنمایی کنید تمام اینترنتو گشتم .
    اینم سایت های مفید :
    http://forum.qt.io/topic/24553/this-application-has-requested-the-runtime-to-terminate-it-in-an-unusual-way
    http://stackoverflow.com/questions/16198649/how-to-run-qt-5-applications-on-other-computers-windows-7
    https://forum.qt.io/topic/26525/deploying-not-possible-anymore-not-dynamically-nor-statically-qt-5-0-2
    http://stackoverflow.com/questions/16708757/qt-5-0-2-and-mingw-4-7-deploy
    http://www.qtcentre.org/threads/53228-Qt5-Microsoft-Visual-C-Runtime-Library-error
    —————————————————————————
    https://download.qt.io/official_releases/qt-installer-framework/
    https://doc.qt.io/qtinstallerframework/index.html

پاسخ دهید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *