جستجو در تالارهای گفتگو
در حال نمایش نتایج برای برچسب های 'c++'.
30 نتیجه پیدا شد
-
سلام دسترسی به اعضای nested یک repeater به چه صورتی هست؟ من با استفاده از دستور زیر به جواب نرسیدم : repeater.itemAt(id).children[0].children[0].children[0].color = "red"; Repeater { id: repeater model: 5 Rectangle { property int radius: 15 gradient: Global.Theme width: radius Button { id:control x: 20 y : -25 Text { id : saveId// saveId text: qsTr(Global.textArray[index]) font : myFont color: Global.Theme ? Global.fontColor_gray : "red" anchors.verticalCenter: parent.verticalCenter anchors.horizontalCenter: parent.horizontalCenter } InnerShadow { //anchors.fill: parent cached: true visible: true horizontalOffset: 0 verticalOffset: 0 radius: 8 samples: 16 color: Global.Theme ? Global.innerShadowColor_gray : "red" smooth: true source: saveId } DropShadow { anchors.fill: saveId source: saveId verticalOffset: 4 //color: "#80000000" color: Global.Theme ? Global.dropShadowColor_gray : "red" radius: 30 samples: 300 } background: Rectangle { implicitWidth: 130 implicitHeight: 55 border.width: control.activeFocus ? 2 : 1 border.color: "darkgray" radius: 10 gradient: Global.Theme ? gradientProvider.gradientThem_1 : gradientThem_0 } onClicked: { } } } }
-
فرض کنیم متدی به نام Calculate برای یکی از کلاسها درون برنامه وجود دارد و برحسب شرایطی فرا خوانی میشود. آیا راهی وجو دارد که بتوان کد داخی آنرا تغییر داد طوری که بعد از تغییر برنامه کد تغییر یافته را اجرا کند همانند proceger در sql server
-
سلام.من یه برنامه ی ساده Hello Word در eclipse و به زبان c++ نوشتم ولی وقتی به پوشه برنامه میرم و فقط فایل EXE رو اجرا میکنم پنجره cmd خیلی سریع باز و بسته میشه و چیزی قابل رویت نیس. دستورات getch() و system("pause") رو هم امتحان کردم ولی نشد.نمیدونم چیکار باید بکنم.کتابخانه ی خاصی و یا دستور خاصی رو باید بنویسم؟ ممنون میشم کمکم کنید
- 4 پاسخ
-
- system pause
- system call
-
(و 1 مورد دیگر)
برچسب زده شده با :
-
نگارش 5.0
هدف از این آموزشها آشنایی با امکاناتی که در Qt میتوان استفاده کرد میباشد، که شامل کدنویسی کمتر، خروجی و طرح های بیشتر و در نهایت استفاده در پلتفرمهای مورد مختلف است. لذا جهت بهرهمندی از این کتابخانه ما با در نظر گرفتن اینکه علاقهمندان با زبان ++C آشنایی لازم را دارند منتشر کردهایم. بنابراین در صورتی که علاقهمندان اطلاعات کافی در رابطه با خود زبان ندارند پیشنهاد میکنیم ابتدا اقدام به تهیه و مطالعه آموزشهای لازم در ++C نمایند که برخی از لینکهای رسمی و استاندارد آن را در زیر اعلام نمودهایم. نوع این کتاب الکترونیکی است، بعد از پرداخت میتوانید بر روی دکمهٔ دریافت فایل در همین صفحه کلیک کرده و آن را دریافت نمایید. عنوان این آموزش "برنامه نویسی ++C همراه با کتابخانه های Qt 5.12.x (سطح مقدماتی ویرایش ۵) میباشد که به صورت زیر فهرست بندی شده است: فصل اول مقدمه کتابخانه Qt قابلیت ها در طراحی فناوری Qt Quick و QML نسخه های کیوت مجوز های موجود در این کتابخانه محیط های توسعه کیوت ویژگی های کیوت پشتیبانی از انواع سیستم عامل ها نصب و پیکربندی Qt فصل دوم انواه پروژه و ایجاد آن انواع پروژه ها ایجاد پروژه فصل سوم ساده ترین برنامه معرفی و کار با Signal و Slot ها و Event ها معرفی و کار با نمایش Windows معرفی و کار با لایه ها زبانه ها و بدنه های در طراحی معرفی و کار با قابلیت های HTML و CSS در طراحی فصل چهارم معرفی و کار با لایه های افقی و عمودی معرفی و کار با لایه های Grid در طراحی فرم معرفی و کار با جدا کننده ها Splitter فصل پنجم معرفی و کار با دایرکتوری ها معرفی و کار با فایل ها / خواندن و نوشتن در آن ها فصل ششم معرفی و کار با برچسب ها Label معرفی و کار با دکمه ها Button معرفی و کار با کنترل ورودی LineEdit معرفی و کار با چک باکس CheckBox معرفی و کار با RadioButton معرفی و کار با Combobox معرفی و کار با لیست ها / ListWidget معرفی و کار با لیست های درختی / TreeWidget معرفی و کار با Action ها معرفی و کار با Slider و Progress ها معرفی و کار با Statusbar در فرم فصل هفتم معرفی و کار با MessageBox معرفی و کار با Timer معرفی و کار با Thread ها فصل هشتم معرفی و کار با Map معرفی و کار با Hash معرفی و کار با QStringList لیست رشته ای فصل نهم معرفی و کار با الگوریتم های معرفی و کار شبکه / دانلود فایل بر اساس پروتکل های HTTP و FTP معرفی و کار با باینری و سریالیز کردن آبجکت ها معرفی و کار با TextStream ها فصل دهم مقایسه انواع حالت های کامپایل در Qt نحوه افزودن دیگر کتابخانه های C++ در محیط Qt Creator و استفاده همراه با کتابخانه Qt نحوه خروجی گرفتن / گسترش (Deployment) در Qt مقایسه و پیکربندی دو موتور قدرتمند OpenGL و ANGLE در پروژه درایور دیتابیس هایی که تحت این کتابخانه پشتیبانی میشوند ساخت راهانداز دیتابیس در پلتفرمهای Linux، macOS و Windows حق نشر کتاب و اهداف در نسخهٔ بعدی کتاب توجه : در داشتن هر گونه انتقاد و پیشنهاد در رابطه با این کتاب با آدرس شخصی نویسنده (kambiz.ceo@gmail.com) مکاتبه نمایید. نکته دوم : کسانی که این کتاب را یک بار خریداری میکنند نسخهٔ به روز رسانی شده آن را به صورت رایگان میتوانند دریافت کنند.﷼۲۰۰٬۰۰۰
-
در این مقاله من قصد دارم در رابطه با تفاوتهای اختصاص دادن حافظه در اِستَک و هیپ توضیحاتی دهم که بسیاری از علاقهمندان راجع به آنها سوال کردهاند. با توجه به اینکه، از اوایل سیستمهای کامپیوتری این تمایز در این وجود داشته است که برنامه های اصلی در حافظه فقط خواندنی مانند ROM ، PROM و یا EEPROM نگه داری میشوند. به عنوان دیگر از زمانی که سیستم ها پیچیدهتر شدند برنامهها از حافظههای دیگری مانند RAM به جای اجرا در حافظه ROM استفاده کردند. این ایده به خاطر این بود که تعدادی از قسمت های حافظه مربوط به برنامه نباید تغییر یابند و در این حالت باید حفظ شوند. در این میان دو بخش .text و .rodata بخشیهایی از برنامه هستند که میتواند به بخش های دیگر برای وظایف خاص تقسیم شوند که در ادامه به آنها اشاره شده است. بخش کد، به عنوان یک بخش متنی (.text) و یا به طور ساده به عنوان متن شناخته میشود. جایی است که بخشی از یک فایل شیء یا بخش مربوطه از فضای آدرس مجازی برنامه که حاوی دستورالعمل های اجرایی است و به طور کلی فقط خواندنی بوده و اندازه ثابتی دارد میباشد. بخش .bss که به عنوانی بخشی ویژه (محل نگه داری اطلاعات تخصیص داده نشده (مقدار دهی نشده)) محلی که متغیرهای سراسری و ثابت با مقدار صفر شروع میشوند. بخش داده (.data) حاوی هر گونه متغیر سراسری و یا استاتیک که دارای یک مقدار از پیش تعریف شده هستند و میتوانند اصلاح شوند. تصویر زیر طرح معمولی از یک حافظه برنامه ساده کامپیوتری را با متن، داده های مختلف، و بخشهای استک و هیپ و bss را نشان میدهد. .section.data < initialized data here> .section .bss < uninitialized data here> .section .text .globl _start _start: <instruction code goes here> برای مثال در کد C به صورت زیر خواهد بود: int val = 3; char string[] = "Hello World"; مقادیر برای این نوع متغیرها در ابتدا در حافظه فقط خواندنی ذخیره میشوند. (معمولا در داخل .text) و در زمان اجرای برنامه که به صورت روتین خواهد بود در بخش .data کپی میشوند. بخش BSS یا همان .BSS در برنامهنویسی کامپیوتر، نام .bss یا bss توسط بسیاری از کامپایلرها و لینکرها برای بخشی از دیتا سِگمنت (Data Segment) استفاده میشود که حاوی متغیر های استاتیک اختصاصی که تنها از بیت هایی با ارزش صفر شروع شده است میباشد. این بخش به عنوان BSS Section و یا BSS Segment شناخته میشود. به طور معمول فقط طول بخش bss نه data در فایل آبجکت ذخیره میشود. برای نمونه، یک متغیر به عنوان استاتیک تعریف شده است static int i; این در بخش BSS خواهد بود. حافظه هیپ (Heap) ناحیهٔ هیپ (Heap) به طور رایج در ابتدای بخشهای .bss و .data قرار گرفته است و به اندازههای آدرس بزرگتر قابل رشد است. ناحیهٔ هیپ توسط توابع malloc, calloc, realloc و free مدیریت میشود که ممکن است توسط سیستمهای brk و sbrk جهت تنظیم اندازه مورد استفاده قرار گیرد. ناحیه هیپ توسط تمامی نخها، کتابخانههای مشترک و ماژولهای بارگذاری شده در یک فرآیند به اشتراک گذاشته میشود. به طور کلی حافطه Heap بخشی از حافظه کامپیوتر شما است که به صورت خودکار برای شما مدیریت نمیشود، و به صورت محکم و مطمئن توسط پردازنده مرکزی مدیریت نمیشود. آن بیشتر به عنوان یک ناحیه شناور بسیار بزرگی از حافظه است. برای اختصاص دادن حافظه در ناحیه هیپ شما باید از توابع malloc(), calloc() که توابعی از C هستند استفاده کنید. یکبار که شما حافظه ای را در ناحیه هیپ اختصاص دهید، جهت آزاد سازی آن باید خود مسئول باشید و با استفاده از تابع free() این کار را به صورت دستی جهت آزاد سازی حافظه اختصاص یافته شده انجام دهید. اگر شما در این کار موفق نباشید، برنامه شما در وضعیت نَشت حافظه (Memory Leak) قرار خواهد گرفت. این بدین معنی است که حافظه اختصاص یافته شده در هیپ هنوز خارح از دسترس قرار گرفته و مورد استفاده قرار نخواهد گرفت. این وضعیت همانند گرفتگی رَگ در بدن انسان است و حافظه نشت شده جهت عملیات در دسترس نخواهد بود. خوشبختانه ابزارهایی برای کمک کردن به شما در این زمینه موجود هستند که یکی از آنها Valgrind نام دارد و شما میتوانید در زمان اشکال زدائی از آن جهت تشخیص نواحی نشت دهنده حافظه استفاده کنید. بر خلاف حافظه اِستک (Stack) حافظه هیپ محدودیتی در اندازه متغیرها ندارد (جدا از محدودیت آشکار فیزیکی در کامپیوتر شما). حافظه هیپ در خواندن کمی کُند تر از نوشتن نسبت به حافظه اِستک است، زیرا جهت دسترسی به آنها در حافظه هیپ باید از اشاره گر استفاده شود. بر خلاف حافظه اِستک، متغیرهایی که در حافظه هیپ ساخته میشوند توسط هر تابعی در هر بخشی از برنامه شما در دسترس بوده و اساسا متغیرهای تعریف شده در هیپ در دامنه سراسری قرار دارند. حافظه اِستک (Stack) ناحیهٔ اِستک (Stack) شامل برنامه اِستک، با ساختار LIFO کوتاه شده عبارت Last In First Out (آخرین ورودی از همه زودتر خارج میشود) به طور رایج در بالاترین بخش از حافظه قرار میگیرد. یک (اشاره گر پشته) در بالاترین قسمت اِستک قرار میگیرد. زمانی که تابعی فراخوانی میشود این تابع به همراه تمامی متغیرهای محلی خودش در داخل حافظه اِستک قرار میگیرد و با فراخوانی یک تابع جدید تابع جاری بر روی تابع قبلی قرار میگیرد و کار به همین صورت درباره دیگر توابع ادامه پیدا میکند. مزیت استفاده از حافظه اِستک در ذخیره متغیرها است، چرا که حافظه به صورت خودکار برای شما مدیریت میشود. شما نیازی برای اختصاص دادن حافظه به صورت دستی ندارید، یا نیازی به آزاد سازی حافظه ندارید. به طور کلی دلیل آن نیز این است که حافظه اِستک به اندازه کافی توسط پردازنده مرکزی بهینه و سازماندهی میشود. بنابراین خواندن و نوشتن در حافظه اِستک بسیار سریع است. کلید درک حافظه اِستک در این است که زمانی که تابع خارج میشود، تمامی متغیرهای موجود در آن همراه با آن خارج و به پایان زندگی خود میرسند. بنابراین متغیرهای موجود در حافظه اِستک به طور طبیعی به صورت محلی هستند. این مرتبط با مفهوم دامنه متغیرها است که قبلا از آن یاد شده است، یا همان متغیرهای محلی در مقابل متغیرهای سراسری. یک اشکال رایج در برنامه نویسی C تلاش برای دسترسی به یک متغیر که در حافظه اِستک برای یک تابع درونی ساخته شده است میباشد. یعنی از یک مکان در برنامه شما به خارج از تابع (یعنی زمانی که آن تابع خارج شده باشد) رجوع میکند. یکی دیگر از ویژگیهای حافظه اِستک که بهتر است به یاد داشته باشید این است که، محدودیت اندازه (نسبت به نوع سیستم عامل متفاوت) است. این مورد در حافظه هیپ صدق نمیکند. خلاصه ای از حافظه اِستک (Stack) حافظه اِستک متناسب با ورود و خروج توابع و متغیرهای درونی آنها افزایش و کاهش مییابد نیازی برای مدیریت دستی حافظه برای شما وجود ندارد، حافظه به طور خودکار برای متغیرها اختصاص و در زمان نیاز به صورت خودکر آزاد میشود در اِستک اندازه محدود است متغیرهای اِستک تنها در زمان اجرای تابع ساخته میشوند مزایا و معایب حافظه اِستک و هیپ حافظه اِستک (Stack) دسترسی بسیار سریع به متغیرها نیازی برای باز پس گیری حافظه اختصاص یافته شده ندارید فضا در زمان مورد نیاز به اندازه کافی توسط پردازنده مرکزی مدیریت میشود، حافظه ای نشت نخواهد کرد متغیرها فقط محلی هستند محدودیت در حافظه اِستک بسته به نوع سیستم عامل متفاوت است متغیرها نمیتوانند تغییر اندازه دهند حافظه هیپ (Heap) متغیرها به صورت سراسری قابل دسترس هستند محدودیتی در اندازه حافظه وجود ندارد تضمینی برای حافظه مصرفی وجود ندارد، ممکن است حافظه در زمانهای خاص از برنامه نشت کرده و حافظه اختصاص یافته شده برای استفاده در عملیات دیگر آزاد نخواهد شد شما باید حافظه را مدیریت کنید، شما باید مسئولیت آزاد سازی حافظه های اختصاص یافته شده به متغیرها را بر عهده بگیرید اندازه متغیرها میتواند توسط تابع realloc() تغییر یابد در اینجا یک برنامه کوتاه وجود دارد که در آن متغیرها در یک حافظه اِستک ایجاد شده اند. #include <stdio.h> double multiplyByTwo (double input) { double twice = input * 2.0; return twice; } int main (int argc, char *argv[]) { int age = 30; double salary = 12345.67; double myList[3] = {1.2, 2.3, 3.4}; printf("double your salary is %.3f\n", multiplyByTwo(salary)); return 0; } ما متغیرهایی را اعلان کردهایم که یک int، یک double و یک آرایه که سه نوع double دارد هستند. این متغیرها داخل اِستک وارد و به زودی توسط تابع main در زمان اجرا حافظه مورد نیاز خود را دریافت خواهند کرد. زمانی که تابع main خارج میشود (برنامه متوقف میشود) این متغیرها همگی از داخل حافظه اِستک خارج خواهند شد. به طور مشابه، در تابع multiplByTwo() متغیر twice که از نوع double است، داخل اِستک وارد شده و در زمان اجرای تابع multiplyByTwo() حافظه به آن اختصاص مییابد. زمانی که تابع فوق خارج شود یعنی به نقطه پایان اجرایی خود برسد، حافظه اختصاص یافته شده به متغیرهای داخلی آن نیز آزاد خواهند شد. به طور خلاصه توجه داشته باشید که تمامی متغیرهای محلی در این نوع تعریف تنها در طول زمان اجرایی زمانی تابع زنده هستند. به عنوان یک یادداشت جانبی، روشی برای نگه داری متغیرها در حافظه اِستک وجود دارد، حتی در زمانی که تابع خارج میشود. آن روش توسط کلمه کلیدی static ممکن خواهد شد که در زمان اعلان متغیر استفاده میشود. متغیری که توسط کلمه کلیدی static تعریف میشود، بنابراین چیزی مانند متغیر از نوع سراسری خواهد بود، اما تنها در داخل تابعی که داخل آن ایجاد شده است قابل مشاهده خواهد بود. این یک ساختار عجیب و غریب است، که احتمالا به جز شرایط بسیار خاص نیازی به آن نباشد. نسخهٔ دیگری از برنامه فوق در قالب حافظه هیپ به صورت زیر است: #include <stdio.h> #include <stdlib.h> double *multiplyByTwo (double *input) { double *twice = malloc(sizeof(double)); *twice = *input * 2.0; return twice; } int main (int argc, char *argv[]) { int *age = malloc(sizeof(int)); *age = 30; double *salary = malloc(sizeof(double)); *salary = 12345.67; double *myList = malloc(3 * sizeof(double)); myList[0] = 1.2; myList[1] = 2.3; myList[2] = 3.4; double *twiceSalary = multiplyByTwo(salary); printf("double your salary is %.3f\n", *twiceSalary); free(age); free(salary); free(myList); free(twiceSalary); return 0; } همانطور که میبینید، استفاده از malloc() برای تخصیص حافظه در حافظه Heap و استفاده از free() جهت آزاد سازی حافظه تخصیص یافته میباشد. این مواجه شدن چیز بسیار بزرگی محسوب نمیشود اما کمی مبهم است. چیز دیگری که باید به آن توجه داشته باشید علامت ستاره (*) است که در همه جای کدها دیده میشود. اینها چه چیزهایی هستند؟ پاسخ این سوال این است : اینها اشاره گر هستند! توابع malloc() و calloc() و free() با اشارهگرهایی مواجه میشوند که مقادیرشان واقعی نیست. اشاره گرها نوع داده ای خاصی در C هستند که آدرس حافظه مربوطه را بر میگردانند. در خط ۵ متغیر twice یک متغیر از نوع double نیست، اما اشاره به یک double دارد. آن آدرس حافظه ای است که نوع double در آن بلوک از حافظه ذخیره شده است. در ++C توسط کلمه کلیدی new که خود آن نیز یک اپراتور محسوب میشود میتوان حافظه ای را در Heap اختصاص داد. به عنوان مثال: int* myInt = new int(256); آدرسهای موجود در حافظه توسط اپراتور new به اشارهگر مربوطه پاس داده میشود. به مثال زیر توجه کنید، متغیر تعریف شده در حافظه اِستک قرار گرفته است: int variable = 256; سوالی که ممکن است افراد کنجکاو از خود بپرسند این است که چه زمانی از Stack و چه زمانی از Heap باید استفاده کنیم؟! خب پاسخ این سوال اینگونه خواهد بود، زمانی که شما نیاز به یک بلوک بسیار بزرگی از حافظه دارید، که در آن یک ساختار بزرگ یا یک ارایه بزرگی را ذخیره کنید و نیاز داشته باشید که متغیرهای شما به مدت طولانی در سرتاسر برنامه شما در دسترس باشند در این صورت از حافظه Heap استفاده کنید. در صورتی که شما نیاز به متغیرهای کوچکی دارید که تنها نیاز است در زمان اجرای تابع در دسترس باشند و قابلیت خواندن و نوشتن سریعتری داشته باشند از نوع حافظه Stack استفاده کنید. فقط فراموش نکنید که حافظه Heap تحت توابع molloc(), realloc(), calloc() و free() مدیریت میشوند. هرچند اشارهگر های هوشمند نیز در ++C وجود دارند اما در بسیاری از مواقع که نیاز است بسیار جزئی و حساس بر روی کدهای خود کار کنید از مدیریت حافظه به صورت دستی استفاده کنید.
-
سلام بر دوستان و اساتید گرامی. پایه و اساس قیمت گذاری یک برنامه C++ چگونه هست؟ با سپاس فراوان.
- 1 پاسخ
-
- c++
- قیمتگذاری
-
(و 3 مورد دیگر)
برچسب زده شده با :
-
آغازی طوفانی برای پیاده سازی یک پیام رسان ساده بر پایه ++C
Max Base نوشته وبلاگ را ارسال کرد در برنامه نویسی
با سلام وقت بخیر, در این مطلب میخواهیم در مورد روش کارکرد پیام رسان ها بیشتر بدانیم و با یکدیگر کد یک پیام رسان ساده را پیاده و بررسی کنیم. طرز کار کرد پیام رسان در نظر داشته باشید که هر پیام رسانی که بر ساختار ها پیاده شده باشد از دو قسمت تشکیل شده است. نرم افزار اصلی برای مدیریت درخواست ها (سرور) نرم افزار برای کاربران (کاربر) به نرم افزار اولی سمت SERVER خواهیم گفت و به بعدی سمت CLIENT خواهیم گفت. روم یا تالار گفتگو ما تنها یک اتاق برای گفتگو در نظر میگیریم و هر کاربری که به سرور متصل شود را در همان تالار اضافه خواهیم کرد. تالار های گفتگو صرفا برای تقکیک سازی ارسال و دریافت ها و محدود کردن بازه ی کاربران مورد نظر... (ممکن است یک کاربر در چند اتاق بطور همزمان باشد.) سیستم های پیام رسان پیشرفته تر مانند تلگرام و ... تالار های زیادی را شامل می شوند. (هر کاربر خودش در کانال و گروه های مختلفی عضو است که هر کدام از آنها یک کانال متفاوت محسوب می شوند.) * دقت شود که منظور از کانال صرفا یک اتاق یا تالار گفتگو است و منظور کانال ارتباطی و پروتکل نیست. نرم افزار اصلی نرم افزار اصلی وظیفه دارد تا تمام کاربرانی که وارد تالار شده اند را به یاد داشته باشد و هر لحظه اماده دریافت درخواست هایی از طرف کاربرانش باشد. و پیام هایی را که از کاربران دریافت می کند برای تمامی کاربران دیگر هم ارسال کند که بسته به خلاقیت و نیاز می تواند هر یک از این بخش ها متفاوت طراحی شود. نرم افزار اصلی باید از قبل اجرا شده باشد. تا کاربران دیگر با استفاده از نرم افزار مخصوص به خودشان بتوانند به سرور متصل شوند و ارسال و دریافت داشته باشند. در نظر داشته باشید که اگر در نرم افزار اصلی اختلالی پیش بیایید و متوقف بشوند. قطا برای تمام کاربران مشکل پیش می آید. مگر اینکه از پایگاه های داده ی داخلی استفاده کرده باشند. (با خلاقیت می توان به گونه های متفاوتی چنین ساختاری را پیاده کرد) نرم افزار کاربران این نرم افزار جذاب ترین بخش است چرا تمام قابلیت هایی را که در اختیار کاربر قرار می دهیم را مستقیما طراحی می کنیم. در نظر داشته باشید که هر چیزی که در این نرم افزار طراحی می شود باید در نرم افزار اصلی پشتیبانی شوند... بنابراین اگر این دو بخش توسط دو فرد یا دو گروه مجزا طراحی می شوند آنها باید توسط داکیومنت ها و جلساتی به نظرات مشابه ای رسیده باشند. (اگرچه اینها تخصص و وظیفه ی تحلیلگر سیستم است! نه بطور همزمان وظیفه توسعه دهنده و برنامه نویس نرم افزار) پیاده سازی یک نمونه اکنون در نظر داریم تا با استفاده از ساختار کتابخانه BoostAsio پروژه ای را با نام BoostAsioChat ایجاد کنیم که در آن می خواهیم یک پیام رسان با حداقل ترین امکانات پایه طراحی کنیم که بیشتر جنبه شخصی و تفریحی دارد. زیرا از ساختار های استاندارد و ایمن و کاربری کاملا بدور است! (می توانید خودتان توسعه دهید و آنرا جالب تر بسازید) ساختار نرم افزار اصلی و سرور را به این صورت تعریف می کنیم : typedef deque<message> messageQueue; class participant { public: virtual ~participant() {} virtual void deliver(const message& messageItem) = 0; }; typedef shared_ptr<participant> participantPointer; class room { public: void join(participantPointer participant); void deliver(const message& messageItem); void leave(participantPointer participant); private: messageQueue messageRecents; enum { max = 200 }; set<participantPointer> participants; }; class session : public participant, public enable_shared_from_this<session> { public: session(tcp::socket socket, room& room) : socket(move(socket)), room_(room); void start(); void deliver(const message& messageItem); private: void readHeader(); void readBody(); void write(); tcp::socket socket; room& room_; message messageItem; messageQueue Messages; }; class server { public: server(boost::asio::io_context& io_context, const tcp::endpoint& endpoint) : acceptor(io_context, endpoint); private: void do_accept(); tcp::acceptor acceptor; room room_; }; int main(int argc, char* argv[]); ساختار نرم افزار کاربر را هم به این صورت تعریف می کنیم : typedef deque<message> messageQueue; class client { public: client(boost::asio::io_context& context, const tcp::resolver::results_type& endpoints) : context(context), socket(context); void write(const message& messageItem); void close(); private: void connect(const tcp::resolver::results_type& endpoints); void readHeader(); void readBody(); void write(); boost::asio::io_context& context; tcp::socket socket; message readMessage; messageQueue writeMessage; }; int main(int argc, char* argv[]); در نظر داریم تا در این پروژه از thread ها نیز استفاده کنیم... در مورد این مفهوم ها می توانید بصورت مجزا تحقیق کنید. بنابراین روش کامپایل این پروژه به این صورت خواهد بود : $ g++ client.cpp -lpthread -o client $ g++ Server.cpp -lpthread -o server آزمایش همانطور که گفته شد در ابتدا نرم افزار اصلی و سرور باید اجرا شود. در اینجا ما تمام ارتباطات شبکه را بر روی یک سیستم در شبکه داخلی برقرار خواهیم کرد... پس نگرانی در مورد ساختار های درونی شبکه و آی پی / دی ان اس / دامین نخواهیم داشت. بنابراین ای پی را می توانید ای پی داخلی یا localhost در نظر بگیرید. برای آزمایش پورت فرضی 4000 را در نظر میگیریم و نرم افزار اصلی را روی این پورت اجرا میکنیم : $ ./server 4000 در این مرحله متوجه می شوید که نرم افزار اصلی با موفقیت اجرا شده است و همچنان اجرا مانده است. بله درست است... نرم افزار اصلی هر لحظه باید منتظر دستور کاربران باشد. اگر لحظه ای برای نرم افزار اصلی اختلالی پیش آید نخواهد توانست دستورات کاربران را انجام یا پاسخ دهد. بنابراین این پردازش را قطع نکنید و اجازه دهید تا نرم افزار اصلی اجرا بماند. در محیط دیگری نرم افزار سمت کاربر را نیز اجرا کنید. این نرم افزار را می توانید به تعداد دلخواه وارد کنید. (همانطور که ممکن است 6 نفر همزمان به سرور متصل باشند / یا ممکن است هیچ فردی به سرور متصل نشوند) ابتدا یک کاربری را به سرور با پورت 4000 و شبکه داخلی وصل می کنیم : $ ./client localhost 4000 first user: you can type message here... حال در محیط دیگری با کاربر جدیدی نیز وارد می شویم : $ ./client localhost 4000 second user: you can type message here... در این پروژه نمونه از کاربران نام کاربری یا نام نمی پرسیم.. و صرفا وقتی وارد محیط گفتگو می شوند... یا زمانی که به سرور متصل می شوند منتظر هستیم تا انها پیامی را بنویسند... هر پیامی را که بنویسند به سرور ارسال می شود و سرور وظیفه دارد تا آنرا برای تمام کاربران بفرستد. و این روند درون یک حلقه بی نهایت تکرار می شوند. پس این ارتباط دو طرفه خواهد بود و هم کاربران برای سرور اطلاعات ارسال می کنند و هم سرور برای کاربران اطلاعات ارسال خواهد کرد. در نظر داشته باشید که کاربر اول می تواند پیامی را بنویسد و به کاربران دیگر ارسال شود. ممکن است کاربر سومی اصلا تصمیمی به نوشتن پیام نداشته باشد و صرفا تمایل به خواندن پیام دیگران داشته باشند. و این کاملا اختیاری است. و ما کاربران را اجباری نمیکنیم. اگرچه شما می توانید با خلاقیت خودتان اینها را با متغییر های کمکی و دستورات شرطی پیاده کنید. کد ها برای پیام ها یک ساختار در نظر میگیریم و بصورت مشترک در هر دو نرم افزار استفاده خواهیم کرد... بنابراین اینرا در هدر پیاده خواهیم کرد. هدر پیام : (message.hpp) #ifndef message_HPP #define message_HPP #include <cstdio> #include <cstdlib> #include <cstring> using namespace std; class message { public: enum { headerLength = 4 }; enum { maxBodyLength = 512 }; message() : bodyLength_(0) { } const char* data() const { return data_; } char* data() { return data_; } size_t length() const { return headerLength + bodyLength_; } const char* body() const { return data_ + headerLength; } char* body() { return data_ + headerLength; } size_t bodyLength() const { return bodyLength_; } void bodyLength(size_t new_length) { bodyLength_ = new_length; if(bodyLength_ > maxBodyLength) bodyLength_ = maxBodyLength; } bool decodeHeader() { char header[headerLength + 1] = ""; strncat(header, data_, headerLength); bodyLength_ = atoi(header); if(bodyLength_ > maxBodyLength) { bodyLength_ = 0; return false; } return true; } void encodeHeader() { char header[headerLength + 1] = ""; sprintf(header, "%4d", static_cast<int>(bodyLength_)); memcpy(data_, header, headerLength); } private: char data_[headerLength + maxBodyLength]; size_t bodyLength_; }; #endif نرم افزار اصلی و سرور : (server.cpp) #include <iostream> #include <cstdlib> #include <deque> #include <memory> #include <list> #include <set> #include <utility> #include <boost/asio.hpp> #include "message.hpp" using boost::asio::ip::tcp; using namespace std; typedef deque<message> messageQueue; class participant { public: virtual ~participant() {} virtual void deliver(const message& messageItem) = 0; }; typedef shared_ptr<participant> participantPointer; class room { public: void join(participantPointer participant) { participants.insert(participant); for(auto messageItem: messageRecents) participant->deliver(messageItem); } void deliver(const message& messageItem) { messageRecents.push_back(messageItem); while(messageRecents.size() > max) messageRecents.pop_front(); for(auto participant: participants) participant->deliver(messageItem); } void leave(participantPointer participant) { participants.erase(participant); } private: messageQueue messageRecents; enum { max = 200 }; set<participantPointer> participants; }; class session : public participant, public enable_shared_from_this<session> { public: session(tcp::socket socket, room& room) : socket(move(socket)), room_(room) { } void start() { room_.join(shared_from_this()); readHeader(); } void deliver(const message& messageItem) { bool write_in_progress = !Messages.empty(); Messages.push_back(messageItem); if(!write_in_progress) { write(); } } private: void readHeader() { auto self(shared_from_this()); boost::asio::async_read(socket, boost::asio::buffer(messageItem.data(), message::headerLength), [this, self](boost::system::error_code ec, size_t) { if(!ec && messageItem.decodeHeader()) { readBody(); } else { room_.leave(shared_from_this()); } }); } void readBody() { auto self(shared_from_this()); boost::asio::async_read(socket, boost::asio::buffer(messageItem.body(), messageItem.bodyLength()), [this, self](boost::system::error_code ec, size_t) { if(!ec) { room_.deliver(messageItem); readHeader(); } else { room_.leave(shared_from_this()); } }); } void write() { auto self(shared_from_this()); boost::asio::async_write(socket, boost::asio::buffer(Messages.front().data(), Messages.front().length()), [this, self](boost::system::error_code ec, size_t) { if(!ec) { Messages.pop_front(); if(!Messages.empty()) { write(); } } else { room_.leave(shared_from_this()); } }); } tcp::socket socket; room& room_; message messageItem; messageQueue Messages; }; class server { public: server(boost::asio::io_context& io_context, const tcp::endpoint& endpoint) : acceptor(io_context, endpoint) { do_accept(); } private: void do_accept() { acceptor.async_accept([this](boost::system::error_code ec, tcp::socket socket) { if(!ec) { make_shared<session>(move(socket), room_)->start(); } do_accept(); }); } tcp::acceptor acceptor; room room_; }; int main(int argc, char* argv[]) { try { if(argc < 2) { cerr << "Usage: server <port> [<port> ...]\n"; return 1; } boost::asio::io_context io_context; list<server> servers; for(int i = 1; i < argc; ++i) { tcp::endpoint endpoint(tcp::v4(), atoi(argv[i])); servers.emplace_back(io_context, endpoint); } io_context.run(); } catch (exception& e) { cerr << "Exception: " << e.what() << "\n"; } return 0; } نرم افزار دوم و سمت کاربر : (client.cpp) #include <iostream> #include <thread> #include <cstdlib> #include <deque> #include <boost/asio.hpp> #include "message.hpp" using boost::asio::ip::tcp; using namespace std; typedef deque<message> messageQueue; class client { public: client(boost::asio::io_context& context, const tcp::resolver::results_type& endpoints) : context(context), socket(context) { connect(endpoints); } void write(const message& messageItem) { boost::asio::post(context, [this, messageItem]() { bool write_in_progress = !writeMessage.empty(); writeMessage.push_back(messageItem); if(!write_in_progress) { write(); } }); } void close() { boost::asio::post(context, [this]() { socket.close(); }); } private: void connect(const tcp::resolver::results_type& endpoints) { boost::asio::async_connect(socket, endpoints, [this](boost::system::error_code ec, tcp::endpoint) { if(!ec) { readHeader(); } }); } void readHeader() { boost::asio::async_read(socket, boost::asio::buffer(readMessage.data(), message::headerLength), [this](boost::system::error_code ec, size_t) { if(!ec && readMessage.decodeHeader()) { readBody(); } else { socket.close(); } }); } void readBody() { boost::asio::async_read(socket, boost::asio::buffer(readMessage.body(), readMessage.bodyLength()), [this](boost::system::error_code ec, size_t) { if(!ec) { cout.write(readMessage.body(), readMessage.bodyLength()); cout << "\n"; readHeader(); } else { socket.close(); } }); } void write() { boost::asio::async_write(socket, boost::asio::buffer(writeMessage.front().data(), writeMessage.front().length()), [this](boost::system::error_code ec, size_t) { if(!ec) { writeMessage.pop_front(); if(!writeMessage.empty()) { write(); } } else { socket.close(); } }); } boost::asio::io_context& context; tcp::socket socket; message readMessage; messageQueue writeMessage; }; int main(int argc, char* argv[]) { try { if(argc != 3) { cerr << "Usage: client <host> <port>\n"; return 1; } boost::asio::io_context context; tcp::resolver resolver(context); auto endpoints = resolver.resolve(argv[1], argv[2]); client c(context, endpoints); thread t([&context](){ context.run(); }); char line[message::maxBodyLength + 1]; while(cin.getline(line, message::maxBodyLength + 1)) { message messageItem; messageItem.bodyLength(strlen(line)); memcpy(messageItem.body(), line, messageItem.bodyLength()); messageItem.encodeHeader(); c.write(messageItem); } c.close(); t.join(); } catch (exception& e) { cerr << "Exception: " << e.what() << "\n"; } return 0; } این پروژه آزمایشی بصورت رایگان و اوپن سورس در اینترنت بخصوص اینجا وجود دارد و می توانید آنرا مستقیما بصورت کامل دانلود کنید. با تشکر, Max Base / مکس بیس -
به نام خدا در این مطلب قصد داریم تا طریقه پیکربندی پایگاه داده MySQL را با استفاده از کامپایلر مایکروسافت بر روی سیستم عامل ویندوز، بررسی نماییم. در ابتدا میبایست پایگاه داده MySQL را بر روی سیستم خود نصب نماییم. بدین منظور به آدرس این آدرس رفته و سپس و نصاب آنلاین یا آفلاین آن را دریافت و بر روی سیستم خود نصب مینماییم. حال لازم است تا مسیر qmake مربوط به کیت مورد نظر واقع در محل نصب کتابخانه کیوت به متغیر محیطی Path سیستم عامل معرفی شود. در اینجا قصد داریم تا از MSVC 2017 64 bit استفاده کنیم که بر روی سیستم عامل 64 بیتی اجرا شده و خروجی دودویی برای سیستم عامل 64 بیتی تولید میکند. مطابق شکل زیر مسیر qmake مورد نظر را به Path سیستم عامل اضافه میکنیم: پس از این کار از منوی Start پوشه Visual Studio 2017 را انتخاب کرده و سپس x64 Native Tools Command Prompt for VS 2017 را انتخاب کرده تا کنسول باز شود. حال میبایست به آدرس محل درایور پایگاه داده کیوت برویم. بدین منظور دستور زیر را در کنسول وارد میکنیم: C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools>F: F:\>cd F:\Softwares\Qt\5.13.1\Src\qtbase\src\plugins\sqldrivers دستور اول به منظور تغییر درایو از C به F وارد شده و دستور دوم آدرس محل نصب کیوت روی سیستم نگارنده مطلب میباشد. حال دستور زیر را وارد میکنیم: qmake -- MYSQL_INCDIR="C:\Program Files\MySQL\MySQL Server 8.0\include" MYSQL_LIBDIR="C:\Program Files\MySQL\MySQL Server 8.0\lib" فراخوانی دستور qmake سبب ایجاد یک makefile شده که بعدا برای کامپایل درایور MySQL استفاده میشود. آدرسهای بالا نیز محل نصب پایگاه داده MySQL در حالت پیشفرض را نشان میدهد. پس از اتمام عملیات نتیجه زیر میبایست حاصل شود: ملاحظه میشود که در مقابل MySql کلمه yes نوشته شده که این به معنی موفقیت آمیز بودن یافتن درایور MySQL میباشد. در نهایت با دستور زیر عملیات کامپایل آغاز میشود: nmake sub-mysql پس از اتمام این مرحله نیز در پایان دستور زیر را اجرا کرده تا فایلهای کامپایل شده، نصب شوند: nmake install محل نصب این فایلهای راه انداز درایور در مسیر زیر میباشد: F:\Softwares\Qt\5.13.1\Src\qtbase\src\plugins\sqldrivers\plugins\sqldrivers در مسیر بالا دو فایل به نامهای qsqlmysql.dll و qsqlmysqld.dll وجود دارد که باید در کنار فایل اجرایی برنامه کامپایل شده قرار گیرد تا برنامه به درستی اجرا شود. همچنین در مسیر: C:\Program Files\MySQL\MySQL Server 8.0\lib فایل libmysql.dll وجود دارد که میبایست در مسیر فایل اجرایی برنامه قرار گیرد. در پایان نوبت به این رسیده تا با ایجاد یک پروژه آزمایشی در Qt Creator بررسی کنیم تا همه چیز به درستی پیکربندی شده باشد. قبل از آن میبایست یک پایگاه داده آزمایشی در MySQL ایجاد کرده و سپس با استفاده از کتابخانه کیوت به آن متصل شویم. ابتدا خط فرمان MySQL را باز کرده و دستور زیر را وارد میکنیم: CREATE DATABASE mydatabase; که mydatabase نام پایگاه داده ایجاد شده میباشد. حال پس از ایجاد یک پروژه ساده در Qt Creator محتویات فایل .pro را مطابق شکل زیر وارد میکنیم: QT += core sql TEMPLATE = app CONFIG += console c++11 CONFIG -= app_bundle SOURCES += \ main.cpp و در فایل main.cpp خواهیم داشت: #include <iostream> #include <QtSql/QSqlDatabase> #include <QtSql/QSqlError> #include <QDebug> using namespace std; int main() { QSqlDatabase db {QSqlDatabase::addDatabase ("QMYSQL")}; db.setHostName ("localhost"); db.setDatabaseName("mydatabase"); db.setUserName ("root"); db.setPassword ("123456789"); if(db.open ()) { qDebug() << "Success!"; } else { qDebug() << db.lastError ().text (); } } با ساخت و اجرا پروژه باید پیام Success! در خروجی نمایش داده شود. این یعنی پایگاه داده MySQL با موفقیت نصب و پیکربندی شده است.
-
وباسمبلی (WebAssembly) یا wasm یک فناوری برنامهنویسی سطحپایین برای استفاده در مرورگر است. هدف اولیهی آن پشتیبانی از کامپایل کدها به سی و سی++ است هرچند که قرار است از سایر زبانها نیز حمایت شود. حال کتابخانهی Qt این امکان را تحت ماژول Qt WebAssembly فراهم میکند تا برنامهی نوشته شده توسط سی++ و کیوت در محیط مرورگر قابل اجرا باشند. این ویژگی در حال حاضر به عنوان پیشنمایش برای نسخهی Qt 5.11 برنامهریزی شده است. کیوت برای ساخت وب اسمبلی دستورالعملهایی را در اینجا آورده است. قبل از هرچیز شما نیاز دارید تا ابزار کامپایلر emsdk را آماده و نصب نمایید. بنابراین دستورات زیر را به ترتیب اجرا کنید. # Get the emsdk repo git clone https://github.com/juj/emsdk.git # Enter that directory cd emsdk # Fetch the latest registry of available tools. ./emsdk update # Download and install the latest SDK tools. ./emsdk install latest # Make the "latest" SDK "active" for the current user. (writes ~/.emscripten file) ./emsdk activate latest # Activate PATH and other environment variables in the current terminal source ./emsdk_env.sh در صورتی که در پیکربندی نیاز به راهنمایی دارید از راهنمای اصلی آن استفاده کنید و یا در همین مرجع در تالارهای گفتمان از ما بپرسید. ما به این ابزار به عنوان ابزار کامپایل-چندمنظوره استفاده خواهیم کرد. برخی از اسکرین شاتها از نتایج خروجی این ماژول به صورت زیر آمدهاند: یک بازی ساده به نام Colliding mice ویژگی پنجرههای گفتگو به نظر میرسد پنجرههای ساخته شده توسط QOpenGLWindow با فریم ریت ۶۰ به خوبی عمل میکنند. البته به نظر میرسد QOpenGLWidget فعلاً شامل برخی از مشکلات است که حل خواهند شد. کامپایلر Emscripten که به عنوان یک کامپایلر منبعباز که بک اند آن بر روی LLVM اجرا میشود کُدهای OpenGL را به WebGL ترجمه میکند. بنابراین محدودیتهایی در نسخههای دسکتاپ و اِمبدها وجود خواهد داشت. نمونه مثال پنجره تحت OpenGL در کنار اینها QtBases و QtDeclarative که از شاخهی Wip/Web Assembly استقاده میکنند، ماژولهای شناخته شدهی کیوت به صورت زیر به کار گرفته میشوند: QtCharts QtGraphicalEffects QtQuickControls QtQuickControls2 QtWebSockets QtMqtt (با استفاده از وب سوکت) برای استفاده از QtMqtt، شما باید کلاس WebSocketIODevice از نمونه مثالی با نام (websocketsubscription) وارد برنامهی خود کنید. نمونه مثالهای ساعت در QML نکته: از آنجا که جاوااسکریپت و وباسمبلی تنها یک نخ (Thread) دارند، QtDeclarative تنها برای یک نَخ (ترد) کار خواهد کرد. در نظر داشته باشید که ماژولهای QtCharts QtGraphicalEffects، QtQuickcontrols، QtQuickControls2 بدون هیچ تغییراتی کار میکنند. ماژول QtChart از نمونه مثال oscilloscope این پروژه به عنوان یک رویکرد جدید و ویژگیای که در آینده میتواند مفید باشد در حال توسعه است. بخش ویکی رسمی آن در این لینک آورده شده است.
-
- وباسمبلی
- webassembly
-
(و 4 مورد دیگر)
برچسب زده شده با :
-
سلام.خسته نباشید. من می خوام از کتابخانه ی nakama در qml استفاده کنم.این کتابخانه به زبان cpp است.برای توابعش می تونم سیگنال و اسلات بنویسم و در qml فراخوانی کنم. ولی data type های سفارشی اون رو نمی دونم چطور در qml ایجاد کنم.مثلا در کد زیر (cpp): NClientParameters parameters; parameters.serverKey = "defaultkey"; parameters.host = "127.0.0.1"; parameters.port = DEFAULT_PORT; NClientPtr client = createDefaultClient(parameters); می خوام NClientParameters در qml قابل دسترسی باشه و بتونم هاست و پورت رو داخل qml تنظیم کنم(مثل بالا). بعد هم به عنوان پارامتر برای تابعم استفاده کنم. لینک کتابخانه cpp: https://heroiclabs.com/docs/cpp-client-guide/#usage
-
اولین پلتفرم آموزشی چند منظورهٔ بومی اگر شما به دنبال فراگیری مهارت خاصی در زندگی خود هستید، فانوکس بستر مناسبی برای شما است؛ نام فانوکس الهام گرفته از فانوس دریایی است که نماد پیدا کردن مسیر و نور راهنما تا رسیدن به مقصد میباشد. هدف : آموزش و یادگیری هوشمند در هر زمان و هر جا برای بهبود زندگی و کسب و کار این تاپیک برای این منظور ایجاد شده است که پروژه معرفی و بازخوردهای آن در این بخش اعلام و اصلاح شوند. بنابراین تمامی دوستان و علاقهمندانی که بازخوردهایی برای آن دارند میتوانند در این بخش آن را اعلام کنند تا به کمک هم آن را اصلاح و توسعه دهیم. نکته: نسخهٔ ریلیز شده ویژگی ثبت خطاها را دارد که به شما اجازه میدهد کد و پیغام خطا را کپی و در اختیار ما قرار دهید. بنابراین شرط جاری روی مُد User و فلگهای Info، Warning، Failed و Critical نیز تنظیم شدهاند که میتوانید در صورت مشاهده آنها را تقسیم بندی کنید. if(DeveloperMode::IsEnable) { Logger::LoggerModel = Logger::Mode::User; Log("Log Message : " + Event , LoggerType::Info); Log("Log Message : " + Event , LoggerType::Warning); Log("Log Message : " + Event , LoggerType::Failed); Log("Log Message : " + Event , LoggerType::Critical); } پیش اطلاعات فنی انجین : سِل Cell رابط کاربری: JavaScript، QML و فناوری Qt Quick کتابخانهها : STL, OpenSSL, Curl و Qt سمت سرور: Php7.2 و MySQLi MariaDB (در آینده همین بخش رو هم احتمالاً با ++C توسعه بدم). رابطهای برنامهنویسی: Restful Api v.1.0 در قالب JSon نسخهٔ فعلی: ۰.۵ آلفا پلتفرمهای پشتیبانی دسکتاپ : Windows, macOS, Linux پلتفرمهای پشتیبانی موبایل و تبلت : iOS, Android, iPadOS معرفی در آیاواستریم نسخهٔ فعلی توسعه یافته : ۰.۵.۳۴۳.۰ ریلیز شده در سه حالت Normal, OpenGLEs و Software Mode هدف از این روش ریلیز این هست که سیستمهایی که دارای کارت گرافیکی ضعیفتر و یا بدون نصب کارت گرافیک و درایور آن هستند را تحت پوشش دهیم، بنابراین نسخهٔ Software Mode تنها مناسب برای سیستمهای اداری و مشابه آن هستند که عموماً خبری از کارت گرافیکی و یا درایورهای نصب شده بر روی آنها نیست ? دوستان توجه داشته باشند که برای بازخوردها و اعلام نظرات توسعه حتماً از مُد اجرای برنامهٔ خودشون و نوع سیستمعامل و شرایط سختافزاریشون مطلع باشند تا بتونیم به درستی مشکلات احتمالی را حل کنیم. در ادامه بعد از نظر نسخهٔ آلفا شروع به بررسی و حل مشکلات احتمالی در مسیر توسعه خواهیم کرد.
-
درود و خستهنباشید به دوستان؛ درحال طراحی یک رابطکابریساده بودهام که خواستم قسمت رنگآمیزی Itemها و Fontها و ... به راحتی قابل تغییر و برنامهریزی باشد. اینکار را با استفاده از یک فایل QML جدا به اسم Style.qml به شکل زیر انجام دادم : pragma Singleton import QtQuick 2.13 Item { property int textinputTextSize : 22 property color transparent : "transparent" property color bluredColor : "#5AAFAAAA" property int tabBarWidth : 50 property int tabBarHeight : 75 property int tabBarIconSize : 44 property int tabBarTextSize : 20 property color tabBarIconColor: "#81D8DE" property color tabBarTextColor: "#059EAB" property color tabBarBackColor: "#0571AB" property alias sahelRegular : sahel_font.name property alias fontAwesome : font_awesome.name FontLoader{ id: sahel_font source: "qrc:/assets/fonts/sahel/Sahel-FD-WOL.ttf" } FontLoader{ id: font_awesome source: "qrc:/assets/fonts/awesome/fontawesome-regular.ttf" } property color mainpageColor : "#E3F2FD" property color mainpageToolbarColor : bluredColor } آیا این روش بهینه و درست است ؟ و یا راه بهتری هم وجود دارد ؟
-
سلام، بنده حدود 6 ماهه که برنامه نویسی با پلتفرم اندروید رو شروع کردم ولی امروز بعد از صحبت با یکی از دوستان برنامه نویس ++C دودل شدم که اندروید رو ادامه بدهم یا یادگیری زبان ++C رو شروع کنم. حالا ممنون میشم بنده رو راهنمایی کنید.
-
سلام به همه دوستان. یک کلاس سی داریم که ارتباط سریال رو انجام میده و من با این کد qmlRegisterType<serialPort>("io.qt.Serial.SerialPort", 1, 0, "SerialPort"); کلاس سی رو نمونه سازی کردم در qml. مشکل اینجاست که چطور زمانی که در سی و توسط پورت سریال اطلاعاتی رو دریافت کردم textarea در qml مقادیر رو نمایش بده. کد دریافت از سریال در کلاس سی ++ QString serialPort::getData() { QByteArray serialData; QString serialBuffer = ""; serialData = _serialport->readAll(); serialBuffer = QString::fromStdString(serialData.toStdString()); qDebug() << serialBuffer; return serialBuffer; } textarea in qml Rectangle { id:containerTextArea width: parent.width anchors.top: container.bottom anchors.bottom: btnClearTextCommunication.top color: "#e0e0eb" TextArea { id:txtCommunication anchors.fill: parent; readOnly: true } } نمونه سازیم کلاس سی++ SerialPort { id:serialport }
-
با سلام و خسته نباشید چطوری میتوان دیتابیس موجود در شبکه اینترنت را خواند ودر کلاینت نشان داد دوستان اگه کسی اطلاعاتی در این مورد داره راهنمایی کنه
-
سلام ... تو فعال سازی اسپلش واسه اندروید به مشکل خوردم . البته کلی لینک رو هم گشتم و همه یه روش رو میگن که جواب هم نمیده. میگن باید تو فایل AndroidManifest.xml از قسمت اسپلش این کار و کنیم . کاشف به عمل اومده قبلا تو سایت یه پست بوده واسه اسپلش و نسخه ی جدید پاک شده . اگه مقدور هست اضافه بشه . ممنون ...
-
سلام خدمت اساتید محترم. اصولا وقتی پروژه ای تحت زبان C++ و در محیط Qt تحویل بگیریم، باید به چه صورتی پروژه رو تحلیل کنیم که کلاس های مرتبط با پروژه رو در Qt پیدا کرده و شروع به سازماندهی و طراحی برنامه کنیم؟ مشکل اصلی من پیدا کردن کلاس مرتبط با پروژه هست. ممنون میشم از اساتید با ذکر مثالی راهنمایی فرمایید.
-
کامبیز اسدزاده یک موضوع را ارسال کرد در <span class="ipsBadge ipsBadge_pill" style="background-color: #38ff7a; color: #000000;" >کتابخانه کیوت (Qt)</span>
همانطور که میدانید محیط توسعهی یکپارچهی نرمافزار Visual Studio به عنوان یکی از جامعترین محیطهای توسعه بسیار شناخته شده است. برنامهنویسان سیپلاسپلاس بسیاری از پروژههای خود را تحت این محیط علاوه بر آن کیوت کریتور توسعه میدهند. کتابخانهی کیوت افزونهای را برای یکپارچه سازی خود با محیط ویژوال استودیو ارائه داده است که در حالت عادی از کتابخانهی Qt به خوبی پشتیبانی میکند و اجازه میدهد تا شما کُدهای خود را که بر اساس کتابخانهی کیوت هستند در محیط ویژوال استودیو توسعه و خروجی بگیرید. اما محدودیتهایی در این افزونه تا به امروز وجود دارد، یکی از آنها عدم هماهنگی و پشتیبانی از زبان QML بر پایه جاوا اسکریپت است. در نسخهی بعدی کیوت یعنی 5.12.0 افزونهی Qt Visual Studio Tools, v2.3.0 نیز منتشر خواهد شد که با نسخههای جدید ویژوال استودیو هماهنگ و به شما امکان اینم را خواهد داد تا بتوانید کدهای نوشته شده توسط QML و JavaScript را اشکالزدایی کنید. این امکان وجود خواهد داشت تا شما هر جایی که نقطهی توقف برای اشکال زدایی ایجاد کرده اید را مورد تجزیه تحلیل قرار خواهید داد. از جمله، تغییر تحولات در ارزشهای متغیرها و دیگر موارد. نسخهی جدید این افزونه به طور کامل با زیرساخت اشکال زدایی QML یکپارچه سازی شده است. که به عنوان بخشی از ماژول Qt QML خدماتی برای اشکال زدایی، بررسی و ثبت و ظبط برنامه را از طریق یک پور TCP فراهم میکند. به صورت پیشفرض ویژگی اشکال زدایی در QML برای ویژوال استودیو فعال است. شما میتوانید آن را در بخش تنظیمات افزونه ویژوال استودیو برای Qt غیرفعال کنید. این ابزار را میتوانید از این بخش دریافت کنید.-
- دیباگینگ
- visual studio
-
(و 7 مورد دیگر)
برچسب زده شده با :
-
همانطور که میدانید یکی از مباحث شاید به ظاهر پیچیده در کیوت برقراری ارتباط بین سیپلاسپلاس و کیواماِل باشد. در این پست من تصمیم گرفتم مثالی را در قالب لیست تماسها ایجاد کنم که شاید بعدها توسعه آن ادامه داشته باشد. فرض کنید قرار است لیستی از تماسها یا کاربران را دریافت و در بخش رابط کاربری خود در قالب یک لیست نمایش دهیم. قبل از هرچیز باید بدانید که برای چنین کاری کلاسی را در سمت بکاِند ایجاد کنید. نام این کلاس را در این مثال ContactList گذاشتهایم. فایل هدر مرتبط با کلاس تماسها به صورت زیر است: // // File : contactlist.h // Class or Function (ContactList) // // Created by Kambiz Asadzadeh on 2018/7/19. // Copyright © 2018 Kambiz Asadzadeh. All rights reserved. // Official Website : http://kambizasadzadeh.com // Powered by : Dotwaves LLC (http://dotwaves.com) // #ifndef CONTACTLIST_H #define CONTACTLIST_H #include <QObject> //Namespace Contact namespace Contact { class ContactList; class ContactList : public QObject { Q_OBJECT Q_PROPERTY ( QString name READ name WRITE setName NOTIFY nameChanged ) Q_PROPERTY ( QString family READ family WRITE setFamily NOTIFY familyChanged ) Q_PROPERTY ( QString phone READ phone WRITE setPhone NOTIFY phoneChanged ) Q_PROPERTY ( QString device READ device WRITE setDevice NOTIFY deviceChanged ) Q_PROPERTY ( QString avatar READ avatar WRITE setAvatar NOTIFY avatarChanged ) Q_PROPERTY ( QString color READ color WRITE setColor NOTIFY colorChanged ) Q_PROPERTY ( QString url READ url WRITE setUrl NOTIFY urlChanged ) public: ContactList(QObject *parent=0); ContactList( const QString &name, const QString &family, const QString &phone, const QString &device, const QString &avatar, const QString &color, const QString &url, QObject *parent=0 ); ~ContactList(); QString name () const; QString family () const; QString phone () const; QString device () const; QString url () const; void setName (const QString &name); void setFamily (const QString &family); void setPhone (const QString &phone); void setDevice (const QString &device); void setUrl (const QString &url); //Avatar of user QString avatar () const; void setAvatar (const QString &image); //Color of user QString color () const; void setColor (const QString &color); signals: void nameChanged (); void familyChanged (); void phoneChanged (); void deviceChanged (); void avatarChanged (); void colorChanged (); void urlChanged (); private: QString m_name; QString m_family; QString m_phone; QString m_device; QString m_avatar; QString m_color; QString m_url; }; } #endif // CONTACTLIST_H قبل از هر چیز دقت کنید که برای استفاده و دسترسی به تمامی آبجکتهای موجود در کیوت نیاز به کلاس QObject خواهیم داشت. بنابراین فایل هدر آن را در فایل خود افزودهایم. فضای نام Contact سپس اعلان کلاس مشتق شده از کلاس QObject مشخص کرده و سپس برای فعال سازی امکان استفاده از سرویس متا آبجکت (به عنوان یک مکانیزم) برای دسترسی به سیگنالها و اسلاتها در کیوت از ماکروی Q_OBJECT استفاد میکنیم. شکل کلی ماکروی Q_PROPERTY Q_PROPERTY(type name (READ getFunction [WRITE setFunction] | MEMBER memberName [(READ getFunction | WRITE setFunction)]) [RESET resetFunction] [NOTIFY notifySignal] [REVISION int] [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] [USER bool] [CONSTANT] [FINAL]) ماکروی Q_PROPERTY جهت اعلان ویژگیهای موجود در اشیاء کلاس به کار گرفته شده است که از کلاس QObject ارث بری میکند. در نظر داشته باشید که این ویژگیهای موجود در اصل همانند اعضای موجود در کلاسها رفتار میکنند، با این تفاوت که در اینجا امکانات و ویژگیهای اضافی بر اساس مکانیزم سیستم متا آبجکت کیوت را ارائه میدهند. ویژگیهای نام، نوع و تابع READ ضروری هستند. نوع میتواند هر نوعی را توسط QVariant پشتیبانی کند، یا توسط کاربر نوع مورد نیاز تعریف شود. آیتمهای دیگر اختیاری هستند، اما یک تابع WRITE رایج است. صفاتهای دیگر به صورت پیشفرض به جز USER که به صورت پیشفرض false است همگی true میباشند. برای مثال Q_PROPERTY(QString title READ title WRITE setTitle USER true) بر اساس همین روش ما پارامترهای کلاس را اعلان و در نهایت توابع، سیگنالها و اعضای خصوصی کلاس را بر اساس نیاز اعلان کردهایم. تعریف کلاس و توابع آن در ادامه به صورت زیر آمده است: // // File : contactlist.cpp // Class or Function (ContactList) // // Created by Kambiz Asadzadeh on 2018/7/19. // Copyright © 2018 Kambiz Asadzadeh. All rights reserved. // Official Website : http://kambizasadzadeh.com // Powered by : Dotwaves LLC (http://dotwaves.com) // #include "contactlist.h" using namespace Contact; ContactList::ContactList(QObject *parent) : QObject(parent) { } ContactList::ContactList( const QString &name, const QString &family, const QString &phone, const QString &device, const QString &avatar, const QString &color, const QString &url, QObject *parent ) : QObject(parent), m_name (name), m_family (family), m_phone (phone), m_device (device), m_avatar (avatar), m_color (color), m_url (url) { } ContactList::~ContactList() {} QString ContactList::name() const { return m_name; } void ContactList::setName(const QString &name) { if (name != m_name) { m_name = name; emit nameChanged(); } } QString ContactList::family() const { return m_family; } void ContactList::setFamily(const QString &family) { if (family != m_family) { m_family = family; emit familyChanged(); } } QString ContactList::phone() const { return m_phone; } void ContactList::setPhone(const QString &phone) { if (phone != m_phone) { m_phone = phone; emit phoneChanged(); } } QString ContactList::device() const { return m_device; } void ContactList::setDevice(const QString &device) { if (device != m_device) { m_device = device; emit deviceChanged(); } } QString ContactList::avatar() const { return m_avatar; } void ContactList::setAvatar(const QString &avatar) { if (avatar != m_avatar) { m_avatar = avatar; emit avatarChanged(); } } QString ContactList::color() const { return m_color; } void ContactList::setColor(const QString &color) { if (color != m_color) { m_color = color; emit colorChanged(); } } QString ContactList::url() const { return m_url; } void ContactList::setUrl(const QString &url) { if (url != m_url) { m_url = url; emit urlChanged(); } } توجه داشته باشید که هر یک از توابع مقادیر ورودی را در قالب پارامترهای ثابت دریافت و در صورتی که اعضای موجود در کلاس مقداری نداشته باشند برابر با پارامتر ورودی خواهند بود. سپس در صورتی که مقدار آنها تغییر یافت وضعیت تغییر آنها توسط emit به عنوان یک پیشپردازندهی از قبل تعریف شده کیوت انتشار (ساطع) خواهد شد. بعد از اعلان و تعریف کلاس مربوطه در فایل main.cpp لیستی را به عنوان دادههای ارسالی ایجاد میکنیم که به صورت زیر آمده است: #include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "contactlist.h" using namespace Contact; int main(int argc, char *argv[]) { QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); QGuiApplication app(argc, argv); QList<QObject*> dataList; dataList.append(new ContactList("کامبیز", "اسدزاده", "09140000000", "Apple iPhone", "https://avatars0.githubusercontent.com/u/4066299?s=460&v=4", "#00D397", "https://github.com/Kambiz-Asadzadeh")); dataList.append(new ContactList("حامد", "مصافی", "09350000000", "Samsung Galaxy", "https://avatars2.githubusercontent.com/u/13809362?s=460&v=4", "#E83B0B", "https://github.com/HamedMasafi")); dataList.append(new ContactList("بهنام", "صباغی", "09190000000", "Google Nexus", "https://avatars3.githubusercontent.com/u/17690495?s=460&v=4", "#E15504", "https://github.com/FONQRI")); dataList.append(new ContactList("آرش", "میلانی", "09140000000", "Apple iPhone", "https://avatars3.githubusercontent.com/u/586816?s=460&v=4", "#3650F7", "https://github.com/arashmilani")); dataList.append(new ContactList("سروش", "ربیعی", "09190000000", "Google Nexus", "https://avatars0.githubusercontent.com/u/920670?s=460&v=4", "#8C56EA", "https://github.com/soroush")); QQmlApplicationEngine engine; QQmlContext *ctxt = engine.rootContext(); qmlRegisterType<ContactList>("api.dotwaves.qml", 1, 0, "Data"); ctxt->setContextProperty("contactModel", QVariant::fromValue(dataList)); engine.load(QUrl(QStringLiteral("qrc:/main.qml"))); if (engine.rootObjects().isEmpty()) return -1; return app.exec(); } تحت کلاس QList اشیاء را به کلاس ساخته شده سفارشی خود به عنوان دادههای جدید معرفی میکنیم. جهت رجیستر (ثبت) کردن کلاس و دادههای سمت بکاِند به سمت فرانت اِند در QML توسط تابع qmlRegisterType به عنوان یک تابع سربار گذاری شده اقدام میکنیم که ساختار آن به صورت زیر است: qmlRegisterType<MyClass>("com.mycompany.qmlcomponents", 1, 0, "CppClass"); این کار باعث میشود شما به کلاسها و توابع کلاس سفارشی خود در سمت فرانت اند دسترسی داشته باشید. این روش در این پروژه اختیاری بوده است و فعلاً آنچنان مهم نیست اما برای اینکه روش آن را بدانید آورده شده است. در ادامه با نمونه گیری کلاس QQmlContext تابع setContextProperty که به عنوان ریشهای از محتوا مجموعهای از خواصهای موجود از مُدل کلاس را بر میگرداند را تنظیم میکند که نام ویژگی را در قالب QVariant برمیگرداند. در نهایت قرار است با استفاده از نوع ListView در سمت QML مقادیر ارسالی از سمت سیپلاسپلاس را دریافت کنیم. به عنوان مثال دریافت نام به صورت زیر خواهد بود: ListView { id:listview model : contactModel delegate: Rectangle { .... ....... Text { id: nameTitle text: model.modelData.name } } نمونه خروجی این مثال به صورت زیر است: برای دسترسی به منبع این مثال میتوانید به گیتهاب من در این لینک مراجعه کنید.
-
با نگاهی به الگوی جستجو تحت الگوریتم Boyer-Moore در استاندارد جدید یعنی C++17 میتوان به کنترل بیشتر و حتی سرعت بسیار بالاتری نسبت به کتابخانهٔ Boost رسید. با استاندارد ۱۷ در سیپلاسپلاس، اکنون میتوانید از الگوریتمهای پیشرفتهتر و بهتری در عین حال سریعتری برای جستجو استفاده کنید. از این پس، شما میتوانید کنترل بیشتر و همچنین افزایش کارآیی امیدوار کنندهای در بسیاری از موارد داشته باشید که به صورت پیشفرض در استاندارد ۱۷ ارائه شدهاست. معرفی روشهای سادهتری برای یافتن الگو در یک رشته O (nm) جایی که n طول تمام رشته است و m طول الگو است وجود دارد. این روشها به عنوان روشهای دوم و بهتری میتوان در نظر گرفته شوند. در C++17 الگوریتم جستجو در استاندارد std::search به دو روش زیر بهروز رسانی شده است: از این پس شما میتوانید از قانون مجوز استفاده از نسخهٔ پیشفرض الگوریتم استفاده کنید، اما به صورت موازی عمل میکند. شما میتوانید یک شیء جستجوگر برای مدیریت جستجو فراهم کنید. بنابراین ما سه نوع جستجوگر خواهیم داشت: default_searcher boyer_moore_searcher boyer_moore_horspool_searcher حالت پیشفرض از جستجو به صورت زیر خواهد بود: #include <iostream> #include <string> #include <algorithm> #include <functional> int main() { std::string in = "Hello, World from new C++ 17"; std::string needle = "C++"; auto it = std::search(in.begin(), in.end(), std::default_searcher(needle.begin(), needle.end())); if(it != in.end()) std::cout << "The string " << needle << " found at offset " << it - in.begin() << '\n'; else std::cout << "The string " << needle << " not found\n"; } پیشپردازش هر دو الگوریتم Boyer Moore و Boyer Moore Horspool از برخی اطلاعات در رابطه با رشته الگو استفاده میکنند تا بتوانند مقایسههای بینظیری را انجام دهند. به منظور هوشمندانهتر شدن هر یک از الگوریتمها یک عمل پیشپردازشی را انجام میدهند که الگوی ورودی را تحلیل میکند. پیچیدگی پیشپردازش معمولاً به اندازهٔ الفبای رشته بستگی دارد. در کتابخانهٔ Boost (بوست) اگر شما با کتابخانهٔ بوست کار کرده اید، ممکن است شما با الگوریتمهای جستجو آشنا باشید. در نسخهٔ ۱.۵۰ (در تاریخ ژوئن ۲۰۱۲ میلادی) مجموعهٔ جدیدی از الگوریتمها به کتابخانه اضافه شده است. در کتابخانه سه شیء جستجوگر وجود دارد: الگوریتم جستجوی Boyer-Moore الگوریتم جستجوی Boyer-Moore-Horspool الگوریتم جستجوی Knuth-Morris-Pratt نحوهٔ استفاده از این روشها در استاندارد ۱۷ چگونه است؟ در سیپلاسپلاس ۱۷ سه نوع سربار اضافی بر روی ویژگیهای std::search اضافه شده است. template<class ForwardIterator, class Searcher> ForwardIterator search( ForwardIterator first, ForwardIterator last, const Searcher& searcher ); هر جستجوگر معمولاً دو ورودی تکرار کننده را میگیرند. شروع و پایان الگو، و سپس یک پیشفرض باینری که معمولاً آن با عملگر برابر است. آنها ممکن است از پارامترهای دیگر نیز استفاده کنند، برای مثال، یک تابع هَش (مخلوط) کننده. در کل، شما میتوانید آن را به صورت زیر استفاده کنید: std::string testString = "Hello Super World"; std::string needle = "Super"; auto it = search(testString.begin(), testString.end(), boyer_moore_searcher(needle.begin(), needle.end())); if (it == testString.end()) cout << "The string " << needle << " not found\n"; برخی از آزمونهای پایه برای آزمایش مخزنی ارائه شده است که در آن نمونه کُد آن آمده است. در این مثال نمونههایی نوشته شده است که برخی از آنها کارایی و سرعت بسیار خوبی را در الگوریتمهای جدید با استفاده از MSVC نشان میدهد. آزمایشها چطور کار میکنند؟ برنامه یک فایل را بارگذاری میکند، مانند کتابی که شامل متنی با ۵۰۰ کیلوبایت اندازه است. تمام محتوای فایل در یک رشتهٔ ورودی ذخیره میشود. یک الگو انتخاب شده است که N آخرین حرف از رشته ورودی است. برنامه از چندین الگوریتم استفاده میکند و بارها در جستجو هر یک از ITER ها را اجرا میکند. برای مثال نسخهٔ std::string::find به صورت زیر آمده است: RunAndMeasure("string::find", [&]() { for (size_t i = 0; i < ITERS; ++i) { std::size_t found = testString.find(needle); if (found == std::string::npos) std::cout << "The string " << needle << " not found\n"; } }); نسخهٔ boyer_moore_horspool به صورت زیر: RunAndMeasure("boyer_moore_horspool_searcher", [&]() { for (size_t i = 0; i < ITERS; ++i) { auto it = std::search(testString.begin(), testString.end(), std::boyer_moore_horspool_searcher( needle.begin(), needle.end())); if (it == testString.end()) std::cout << "The string " << needle << " not found\n"; } }); در اینحا نتیجه بر روی سخت افزار با پردازندهٔ i7 4720HQ و Win 10 همراه با MSVC 2017 15.8 ریلیز ۶۴ بیت میباشد. الگو از ۱۰۰۰۰ حرف انتهای متن ورودی تشکیل شده است: .\searchers.exe ..\..\SampleBooks\book-test.txt 1000 10000 string length: 547412 test iterations: 1000 pattern length: 10000 string::find: 693.449 ms default searcher: 1102.25 ms boyer_moore_searcher: 133.558 ms boyer_moore_horspool_searcher: 37.0234 ms الگو در اینجا اکنون ۱۰۰ حرف آخر از متن ورودی است: .\searchers.exe ..\..\SampleBooks\book-test.txt 1000 200 string length: 547412 test iterations: 1000 pattern length: 200 string::find: 158.612 ms default searcher: 467.518 ms boyer_moore_searcher: 58.8752 ms boyer_moore_horspool_searcher: 56.7017 ms البته توجه داشته باشید که، نتایج نمونه نیاز به تحقیق بیشتری دارند. برای مثال در الگوهای کوتاه، استفاده از روش string::find معمولاً سریعتر است. بنابراین، الگوریتم Horspool سریعتر از الگوریتم boyer_moore در این مورد بوده است. واقعیت مهم در مورد std::search این است که آن یک الگوریتم عمومی است! بنابراین شما میتوانید آن را فقط برای رشتهها استفاده کنید. در اینجا مثالی آورده شده است که برای جستجوی یک الگو از شمارههای موجود در یک بردار از عددهای صحیح است. std::vector<int> testVector(1000000); std::iota(testVector.begin(), testVector.end(), 0); std::vector vecNeedle(testVector.end() - 1000, testVector.end()); auto it = std::search(testVector.begin(), testVector.end(), std::boyer_moore_horspool_searcher( vecNeedle.begin(), vecNeedle.end())); if (it == testVector.end()) std::cout << "The pattern " << needle << " not found\n"; خلاصهٔ نتیجه در این مقاله به صورت مختصر در رابطه با قابلیتهای جدیدی را که در سیپلاسپلاس ۱۷ دریافت کردهایم اشاره شده است. مهم این است که بدانید الگوریتمهای جدید همیشه سریعتر از std::string::find (برای رشتهها) نیستند.
-
- سیپلاسپلاس
- جستجو
- (و 6 مورد دیگر)
-
با درود، وجود کتابخانههای متعدد برای توسعهی رباتهای تلگرام برای زبانها و چهارچوبهای مختلف، و عدم وجود یک کتابخانه بهروز برای ++C و کیوت باعث شد تا توسعهی این پروژه را آغاز کنم. امیدوارم این پروژه برای توسعهدهندگان مفید واقع شود. عنوان: پروژهی TarnaBot توضیحات: یک کتابخانه بر پایه فریمورک کیوت (Qt) که به توسعهدهندگان امکان برنامهنویسی رباتهای تلگرام را میدهد. زبانها و فناوریهای استفاده شده: ++C فریمورک ها و کتابخانهها: کیوت (Qt) نسخه ۵ ابزارِ ساخت: qmake نوع پروژه: متن باز (Open source) مجوز: LGPL v3 نویسندگان: علی رشیدی وضعیت: در حال توسعه - پایدار (stable) مثالها و مستندات به زودی اضافه خواهند شد.
-
کامبیز اسدزاده یک موضوع را ارسال کرد در <span class="ipsBadge ipsBadge_pill" style="background-color: #e62f3d; color: #ffffff;" >برنامه نویسی در C و ++C</span>
مراحل ساخت برنامه در زبان سیپلاسپلاس پیش نویس ۰.۶ قبل از هر چیز به اینفوگرافی زیر توجه کنید که مراحل ساخت برنامه در سیپلاسپلاس را نشان میدهد. مقدمهای بر همگردانی (کامپایل) و اتصال (لینک کردن) این سند مرور مختصری در رابطه با مراحل را برای شما فراهم میکند تا به شما در درک دستورات مختلف برای تبدیل و اجرای برنامهٔ خودتان کمک کند. تبدیل مجموعهای از فایلهای منبع و هدر در سیپلاسپلاس به یک فایل خروجی و اجرایی در چندین گام (به طور معمول در چهار گام) پیشپردازنده (Preprocessors)، کامپایل و گردآوری (Compilation)، اسمبلر (Assmbler) و پیوند دهنده (Linker) تقسیم میشود. قبل از هر چیز اگر در محیط توسعهٔ Qt Creator داخل فایل .pro مقدار زیر را وارد کنید، تا بتوانید فایلهای ساخته شدهٔ موقت در زمان کامپایل را مشاهده کنید. QMAKE_CXXFLAGS += -save-temps این دستور اجازهٔ آن را خواهد داد تا فایلهایی با پسوند .ii و .s در شاخهٔ بیلد پروژه تولید شوند که در ادامه به آنها اشاره شده است. تعریف پیشپردازنده پیشپردازندهها (Preprocessors) درواقع دستوراتی هستند که اجازه میدهند تا کامپایلر قبل از آغاز کردن مراحل کامپایل دستوراتی را دریافت کند. پیشپردازندهها توسط هشتگ (#) مشخص میشوند این نماد در سی++ مشخص میکند که دستور فوق از نوع پیشپردازنده میباشد که نتیجهٔ آن در قالب ماکرو (Macro) در دسترس خواهد بود. برای مثال ماکروی __DATE__ توسط پیشپردازندهها از قبل تعریف شده است که مقدار تاریخ و زمان را بازگشت میدهد. بنابراین هرکجا که از آن استفاده شود کامپایلر آن را جایگزین متن خواهد کرد. در شکل زیر مرحلهای که از پیشپردازندهها استفاده میشود آمده است: پیشپردازنده، کامپایل (گردآوری کردن)، لینک (پیوند کردن) و ساخت برنامه اجرایی فرایند تبدیل مجموعهای از فایلهای متنی هِدر و سورس سی++ را «ساخت» یا همان Building میگویند. از آنجایی که ممکن است کُد پروژه در بسیاری از فایلها هدر و سورس سی++ توسعه و گسترش یابدمراحل ساخت در چند گام کوچک صورت میگیرد. یکی از رایجترین موارد در مراحل گردآوری (ترجمهٔ یک کد سیپلاسپلاس به دستورالعملهای قابل فهم ماشین) است. اما گامهای دیگری نیز وجود دارد، پیشپردازنده و لینک (پیوندها) این بخش به طور خلاصه توضیح میدهد که چه اتفاقی در هر یک از مراحل رُخ میدهد. یک کامپایلر یک برنامهٔ خاص است که پردازش اظهارات (دستورات) نوشته شده در یک زبان برنامهنویسی خاص را به یک زبان ماشین که قابل فهم برای پردازنده میباشد تبدیل کند. به طور معمول یک برنامهنویس با استفاده از یک ویرایشگر که به محیط توسعهٔ یکپارچهٔ نرمافزار (IDE) مشهور است توسط زبان برنامهنویسی مانند ++C دستورات (اظهارات) را مینویسد. فایل ایجاد شده با نام (filename.cpp در زبان برنامهنویسی سیپلاسپلاس) شامل محتوایی است که معمولاً به عنوان دستورات برنامهنویسی سطح بالا نامیده میشود. سپس برنامهنویس کامپایلرِ مناسب برای زبان برنامهنویسی مانند سی++ را اجرا میکند و نام فایلهایی که حاوی دستورات هستند را برای کامپایل مشخص میکند که این انتخاب و مشخص سازی توسط IDE به راحتی قابل مدیریت است. پس از آن، کار کامپایلر این است که فایلهای منبع .cpp را جمع آوری کرده و پیشپردازندهها را بررسی کند تا دستورات احتمالی را اجرا نماید که نتیجهٔ این مرحله در فایلی با پسوند .ii ر قالب filename.ii تولید میشود که در این فرایند نیز خط به خط کُدهای موجود در آنها را بررسی میکند تا خطاهای احتمالی نحو (سینتکس - Syntax) بررسی میشود و آنها را به طور ترتیبی به دستورالعملهای سطح ماشین تبدیل کند. توجه داشته باشید که هر نوع پردازندهٔ کامپیوتر دارای مجموعهای از دستورالعملهایِ ماشین خودش است. بنابراین کامپایلر تنها برای سی++ نیست، بلکه برای اهداف و مقاصد خاص هر پلتفرم است. پس کدهایی که توسط پیشپردازنده سیپلاسپلاس به زبان اسمبلی برای معماری مورد نظر در پلتفرم مقصدترجمه شدهاند نتایج آن در فایلی با پسوند .ss در قالب filename.ss قابل نمایش هستند که در حالت عادی قابل رویت نیست. توجه داشته باشید که باید در این مرحله باید مشخص شود برنامه قرار است توسط چه نوع پردازندهای تحتِ چه نوع معماری مونتاژ (اسمبل) شود. برای مثال پردازندهها با انواع معماریهای مختلف وجود دارند که برخی از آنها به صورت x86-x64، x64، ARMv7، aarch64 غیره ... میباشند. شکل یک (کامپایل یک فایل منبع ++C) مرحلهٔ سوم را در نظر داشته باشید که عمل کامپایل فایل سیپلاسپلاس در دو مرحله قبلی یک فایل اجرایی را تولید نمیکند. برنامهای که توصیف شده است، احتمالاً توابعی را در رابطهای برنامهنویسی (API) و یا توابع ریاضی یا توابع مرتبط با I/O را فراخوانی کند که ممکن است شامل فایلهای هدر مانند iostream یا fstream و حتی ماژولهای دیگری که در زبان تعبیه شدهاند را داشته باشد که فایل تولید شده توسط کامپایلر در این مرحله یک فایل شیء نامیده میشود که با پسوند .o به صورت filename.o تولید خواهد شد که علاوه بر دستورالعملهای تبدیل شده به کد ماشین، شامل توابع و دستورالعملهای خارجی نیز میباشد. هرچند در این مرحله دستورات تبدیل به دستورالعملهای قابل فهم توسط پردازنده شدهاند اما فعلاً قابل اجرا نیستند چرا که باید این توابع خارجی افزوده شده را به آن لینک کرد که در مرحلهٔ بعد یعنی مرحلهٔ چهارم اتفاق میافتد. در نهایت مرحلهٔ چهارم فایل با پسوند .o که شامل کدهای تولید شده توسط کامپایلر به زبان ماشین است که پردازندهها میتوانند این دستورات را درک کنند که همراه با کدهای تولید شدهٔ هر کتابخانهٔ دیگری که مورد نیاز است توسط لینکر (لینک شده) و در نهایت جهت تولید یک فایل اجرایی مورد استفاده قرار میگیرند که نوع آن فایل از نوع اجرایی یا در واقع Executable File خواهد بود. شرح کامل فرایند ساخت فایل اجرایی اکثر پروژهها دارای مجموعهای از فایلهای هدر سی++ هستند، که امکان ماژولار شدن در آن را فراهم میکند و مجموعهای از آن میتواند به عنوان بخشهای کوچکی از برنامه محسوب شوند. برای ساخت چنین پروژههایی هر فایل سیپلاسپلاس باید کامپایل شود و سپس فایلهای ساخته شده در قالب شیء (آبجکت) باید همراه توابع و کتابخانههای دیگر لینک (پیوند) شوند. البته هر گام از مراحل کامپایل شامل یک مرحله پیشپردازنده است که دستورالعمل # عمل تغییرات و اصلاحیهها را در فایل متن اعمال میکند. شکل زیر فرایند ساخت چند فایل به صورت همزمان را نشان میدهد: در ادامهٔ این مقاله، مطلبی مرتبط با تنظیمات بیشتر از کامپایلر آمده است که میتوانید آن را مورد مطالعه قرار دهید. -
با سلام، همانطور که میدانید سیستمهای مدیریت محتوا به عنوان سیستم پویا برای مدیریت محتوای یک وبسایت بسیار مفید هستند. حال آنکه یک سیستم مدیریت محتوا فراتر از یک سیستم نرمافزاری جهت مدیرین محتوای وبسایت توسعه یابد بسیار مفید خواهد بود. قابلیتها و ویژگیها با استفاده از سیستم مدیریت محتوای جگوار (Jaguar) ما میتوانیم برای مشتریان خود یک سیستم مدیریت چند منظوره با قابلیتهای کاملاً پویا ارائه دهیم که هر استارتاپی میتواند کسبوکار خود را تحت آن توسعه دهد. این سیستم دارای قابلیتهای چند سکویی و چند منظوره میباشد که یکی از قابلیتهای برجستهٔ آن پشتیبانی از سیستم چند زبانه میباشد. این سیستم در پلتفرمهای وب، موبایل و دسکتاپ توسعه داده شده است. عنوان: پروژهٔ جگوار (Jaguar) توضیحات: سیستم مدیریت محتوای چند منظوره و پیشرفته زبانها و فناوریهای استفاده شده: زبانهای Php7, JavaScript, CSS3, HTML5 فریم وُرک و کتابخانهها: کتابخانهٔ JQuery , Angular.JS, BootStrap4 نوع پروژه: تجاری (انحصاری شرکتِ Dotwaves LLC) نویسندگان: کامبیز اسدزاده وضعیت: در حال توسعه حق چاپ و تکثیر: شرکت داتویوز این محصول بر پایه موتور سِل توسعه داده شده است. برخی از تصاویر مرتبط با این محصول:
- 1 پاسخ
-
- سیستم مدیریت محتوا
- cms
-
(و 8 مورد دیگر)
برچسب زده شده با :
-
با سلام. سوالی که داشتم این هست که چطور میشه به وسیلهی Qml یک عکس رو آپلود کرد؟ آیا کسی تا حالا این کار رو انجام داده؟ من فقط میخوام از کد Qml استفاده کنم ولی اگه مجبور شدم از C++ هم استفاده می کنم.
-
کامبیز اسدزاده یک موضوع را ارسال کرد در <span class="ipsBadge ipsBadge_pill" style="background-color: #38ff7a; color: #000000;" >کتابخانه کیوت (Qt)</span>
این تاپیک مخصوص نمونه مثالهایی از پروژهها، ماژولها، کامپوننتها و افزونههایی میباشد که به صورت استاندارد و مدرن توسط سیپلاسپلاس و جاوااسکریپت تحت فناوری Qt Quick طراحی میشوند. بدون هیچگونه تعارفی باید بگوییم هر نرمافزار (اپلیکیشن) و یا محصولی که ساخته میشود باید مطابق استانداردهایی که مهندسین طراحی بر روی آن تاکید دارند توسعه یابد. این استانداردها ممکن است شامل اصول کُدنویسی، الگوهای کدنویسی و یا قوانین روانشناسی رنگها، چیدمان اشیاء و هر موردی که میتواند در نتیجهی آن تاثیر مثبت داشته باشد مهم هستند. با هدف اینکه میخواهیم نمونه مثالهایی را برای تازه واردین قرار دهیم تا بتوانند به درستی ونحوهی صحیح طراحی و پیاده سازی دو بخش بکاِند و فرانتاِند آشنا شوند، نمونه مثالهای شما باید دارای شرایط زیر باشند ساختار استاندارد کلاسها و توابع در سمت سیپلاسپلاس استفاده از اشاره گرهای هوشمند و یا رعایت اصول مدیریت حافظه استفاده از ماکروهای سفارشی iOS، Android، Windows، macOS و لینوکس جهت مدیریت بهتر بعضی از ویژگیهای منحصربفرد سیستمعاملها تا جایی که میتوانید سعی کنید از ابزارهای qmake و qbs در این نمونه مثالها استفاده کنید رعایت رنگبندی و همچنین اصول UX درست مهم است مثال شما باید برگرفته و بر اساس استانداردهای توصیه شدهی doc.qt.io باشد. استفادهی بهینه از لنگرها و همچنین ترازبندی صحیح لایهها و نگهدارندهها در سمت QML استفاده از تصاویر و یا قالبهای استاندارد و سبک مانند SVG, PNG و base64 استفاده از فونت آیکونیکها مانند (FontAwesome) این پست ممکن است ویرایش و یا به روزرسانی شود. در ادامه شما میتوانید بر اساس شرایطی که ذکر شده است و با توجه به استانداردهای Google Material، Microsoft Fluent و همچنین Apple Human Interface نمونه مثالهای خود را ارائه دهید که برخی از مثالهای استاندارد در زیر آمده اند.- 1 پاسخ
-
- رابطکاربری
- ux
-
(و 7 مورد دیگر)
برچسب زده شده با :