رفتن به مطلب
مرجع رسمی سی‌پلاس‌پلاس ایران

کامبیز اسدزاده

بنیـــان گذار
  • تعداد ارسال ها

    505
  • تاریخ عضویت

  • روز های برد

    266

پست ها ارسال شده توسط کامبیز اسدزاده


  1. جزئیات، به‌روز رسانی‌ها و ویژگی‌های C++23

    همانطور که می دانیم، مدیریت خطا در سی‌پلاس‌پلاس به وسیلهٔ بیانیه‌های try، catch و throw انجام می‌شود. این ویژگی به برنامه‌نویس این امکان را می‌دهد که خطاها را شناسایی کرده و به دسته‌بندی کرده و سپس به شکل مناسبی برخورد کند.

    همچنین کلاس‌هایی مانند std::exception یک کلاس پایه در سی‌پلاس‌پلاس است که برای نمایش استثناء‌ها (خطاها) در هنگام اجرای برنامه استفاده می‌شود. این کلاس یک رابط عمومی به نام what دارد که متنی که توضیح خطا را حاوی می‌شود، به عنوان یک رشته C-style (const char*) باز می‌گرداند.

     

    مدیریت خطای جدید std::expected معرفی شده در استاندارد ۲۳

    در استاندارد جدید ۲۳ گزینهٔ std::expected معرفی شده‌است که اجازه می‌دهد خطاها را بهتر مدیریت کنیم.

    • این نوع داده به شما این امکان را می‌دهد که یک عدد بازگشتی معمولی (نتیجه موفقیت‌آمیز) یا یک کد خطا (نتیجه ناموفق) را با هم در یک متغیر ذخیره کنید.
    • برای برنامه نویسانی که از این نوع داده استفاده می‌کنند، کد برنامه خواناتر و قابل‌فهم‌تر است.
    • استفاده از std::expected معمولاً در جاهایی مناسب است که خطاها قابل پیش‌بینی و مدیریت شوند.

    در زیر یک نمونه کد در قالب مثال بر پایهٔ سی‌پلاس‌پلاس جدید آورده شده است:

    import <print>;
    import <expected>;
    
    enum class ErrorType { InvalidName, NotFound, OtherError };
    
    auto getName(std::string name) -> std::expected<std::string, ErrorType>
    {
        if (name != "Kambiz") {
            return std::unexpected(ErrorType::InvalidName);
        }
        return name;
    }
    
    auto main() -> int {
    
        auto result = getName("Compez");
    
        if (result.has_value()) {
            std::println("Result: {}", result.value());
        } else {
            ErrorType error = result.error();
            switch (error) {
            case ErrorType::InvalidName:
                std::println("Error: Invalid Name!");
                break;
            case ErrorType::NotFound:
                std::println("Error: Not Found!");
                break;
            case ErrorType::OtherError:
                std::println("Error: Other Error!");
                break;
            }
        }
    
        return 0;
    }

    در اینجا، یک تابع به نام getName تعریف شده است که یک نام به عنوان ورودی دریافت می‌کند و یک std::expected را باز می‌گرداند. اگر نام "Kambiz" نباشد، یک std::unexpected با ErrorType::InvalidName ایجاد می‌شود و اگر نام معتبر باشد، خود نام به عنوان مقدار بازگشتی استفاده می‌شود.

    سپس در تابع main، ما از تابع getName برای دریافت نتیجه استفاده می‌کنیم. اگر نتیجه دارای مقدار باشد (با فراخوانیhas_value())، آن مقدار با استفاده از value() چاپ می‌شود. اگر نتیجه دارای خطا باشد، ما با استفاده از error() نوع خطا را دریافت کرده و با استفاده از یک switch به تصمیمات مرتبط با نوع خطا می‌رسیم و پیام مناسب چاپ می‌شود. توجه داشته باشید که در دسترسی بهerror()، ممکن است بعضی از پیاده‌سازی‌های expected به جای error() از value() برای دسترسی به خطا استفاده کنند.

    به نظر می‌رسد این ویژگی می‌تواند به صورت چشم‌گیری روش مدیریت خطاها را بهبود سازد.


    ماژول‌ها و وارد کردن کتابخانه‌های استاندارد به پروژه به صورت ساده و بهینه توسطimport std; و import std.compat; در استاندارد ۲۳

    قبلاً من توی پروژهٔ سل و حتی قالب PT یه بخشی برای بهبود و بهینه‌سازی فایل‌های کتابخانهٔ استاندارد (هدر فایل‌ها) به عنوان pch گذاشته بودم. این کار باعث می‌شد که پروژه در سرتاسرش هر جا اس کتابخانهٔ STL استفاده می‌شد رو نیازی به وارد کردن فایل‌ها نباشه. این کار موجب بهینگی کامپایل می‌شه. حالا توی استاندارد ۲۳ چیزی مشابه این موضوع رو به صورت استاندارد شده تعبیه کردن که از شلوغی و اضافات لازم به شدت جلو گیری می‌کنه و سرعت کامپایل هم افزایش پیدا می‌کنه. ⚡

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

    #include <algorithm>
    #include <array>
    #include <print>
    
    auto main() -> int
    {
        std::array<int, 10> s {5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
        std::sort(s.begin(), s.end());
        for(auto el : s)
        {
            std::println("Sorted Index: {}", el);
        }
    }
    

    کافیه به شیوهٔ زیر بنویسید:

    import std;
    
    auto main() -> int
    {
        std::array<int, 10> s {5, 7, 4, 2, 8, 6, 1, 9, 0, 3};
        std::sort(s.begin(), s.end());
        for(auto el : s)
        {
            std::println("Sorted Index: {}", el);
        }
    }
    

    در واقع استفاده از ;import std تمامی کتابخانه‌های استاندارد رو وارد می‌کنه و استفاده از ;import std.compat مثل همون هست اما با تفاوت این ‌که کتابخانه‌های عمومی C رو هم وارد خواهد کرد. فکرشو بکن ده‌ها و صد‌ها کتابخانه STL رو وارد فایل‌ها می‌کنی! اما الآن کافیه همین یه خط رو بنویسی 🙂 دنیای ماژول‌ها در سی‌پلاس‌پلاس جدید خیلی تمیزه!


  2. کتابخانهٔ Boost: یک راهکار قدرتمند برای توسعهٔ برنامه‌های سی‌پلاس‌پلاس

    مقدمه

    کتابخانهٔ Boost یکی از مهم‌ترین ابزارها در دنیای برنامه‌نویسی سی‌پلاس‌پلاس است. این کتابخانه کاملاً رایگان بوده و مجموعه‌ای گسترده از کتابخانه‌ها و ابزارهای مفید برای توسعه‌دهندگان این زبان فراهم می‌کند. در این مقاله، به بررسی ویژگی‌ها، اهمیت و کاربرد کتابخانهٔ Boost در سی‌پلاس‌پلاس می‌پردازیم.

    pre-boost.jpg

    ۱. ویژگی‌های کتابخانهٔ Boost

    کتابخانهٔ Boost دارای ویژگی‌های فراوانی است که آن را از سایر کتابخانه‌ها متمایز می‌کند. به برخی از این ویژگی‌ها در زیر اشاره خواهیم کرد:

    الف. تعداد زیادی ابزار و کتابخانه

    Boost شامل تعداد زیادی از کتابخانه‌ها و ابزارهای مفید است که برای تسهیل و افزایش کارایی در توسعهٔ نرم‌افزارهای سی‌پلاس‌پلاس به کار می‌روند. برخی از این کتابخانه‌ها شامل:

    • کتابخانهٔ Boost.Filesystem: برای مدیریت فایل‌ها و دایرکتوری‌ها در سیستم عامل استفاده می‌شود.
    • کتابخانهٔ Boost.Thread: برای پشتیبانی از نخ‌ها (Thread) و همزمان‌سازی استفاده می‌شود.
    • کتابخانهٔ Boost.Regex: برای پردازش و مدیریت عبارات باقاعده (Regular Expressions) به کار می‌رود.

    ب. پشتیبانی از استانداردهای مدرن

    Boost به خوبی استانداردهای مدرن سی‌پلاس‌پلاس را پشتیبانی می‌کند. این کتابخانه ابزارها و قابلیت‌هایی ارائه می‌دهد که توسعه‌دهندگان را در استفاده از قابلیت‌های جدید و بهبود‌یافتهٔ زبان کمک می‌کند. با استفاده از Boost، می‌توانید از استانداردهای مدرن مانند C++11 و C++14 بهره‌برداری کنید و کدهای بهتری بنویسید.

    ۲. اهمیت Boost برای توسعهٔ سی‌پلاس‌پلاس

    کتابخانهٔ Boost اهمیت فراوانی در توسعهٔ سی‌پلاس‌پلاس دارد. به دلیل وجود ابزارها و کتابخانه‌های متنوع، Boost به توسعه‌دهندگان این زبان کمک می‌کند تا برنامه‌های قدرتمندی را با سرعت و کارایی بالا ایجاد کنند. همچنین، استفاده از Boost باعث می‌شود که کد نوشته شده توسط توسعه‌دهندگان با استانداردهای مدرن و قابلیت‌های بهبودیافتهٔ زبان همخوانی داشته باشد.

     

    ۳. کاربرد کتابخانهٔ Boost در سی‌پلاس‌پلاس

    کتابخانهٔ Boost در سی‌پلاس‌پلاس در بسیاری از زمینه‌ها کاربرد دارد. در ادامه به برخی از کاربردهای این کتابخانه می‌پردازیم:

    الف. توسعهٔ برنامه‌های شبکه

    Boost ابزارها و کتابخانه‌های قدرتمندی برای توسعهٔ برنامه‌های شبکه در سی‌پلاس‌پلاس فراهم می‌کند. از طریق Boost.Asio می‌توانید به راحتی بر

    نامه‌هایی با استفاده از پروتکل‌های مختلف شبکه مانند TCP و UDP بنویسید و با سرعت و کارایی بالا با ارتباطات شبکه کار کنید.

    ب. پردازش و مدیریت رشته‌ها

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

    ۴. مزایای استفاده از کتابخانهٔ Boost

    استفاده از کتابخانهٔ Boost در توسعهٔ پروژه‌های سی‌پلاس‌پلاس دارای مزایای بسیاری است. به دلیل ویژگی‌ها و قابلیت‌های فراوان این کتابخانه، می‌توانید از مزایای زیر بهره‌برداری کنید:

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

    ب. پشتیبانی از چندپلتفرم
    کتابخانهٔ Boost بر روی چندپلتفرم قابل استفاده است و از این جهت بسیار مفید است. اگر برنامهٔ شما باید روی سیستم‌عامل‌های مختلف اجرا شود، Boost می‌تواند به شما در این مسئله کمک کند. شما می‌توانید از ابزارها و قابلیت‌های Boost استفاده کنید تا برنامهٔ خود را به طور مستقل از سیستم‌عامل مقصد اجرا کنید و از سهولت توسعه و نگهداری برخوردار شوید.

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

    ۵. کاربردهای کتابخانهٔ Boost

    کتابخانهٔ Boost به دلیل قابلیت‌ها و امکانات فراوان خود، در زمینه‌های مختلفی از جمله زیر استفاده می‌شود:

    الف. توسعهٔ برنامه‌های کاربردی
    Boost ابزارها و کتابخانه‌هایی را فراهم می‌کند که می‌تواند در توسعهٔ برنامه‌های کاربردی مختلف مفید باشد. مثلاً Boost.Asio برای برنامه‌نویسی شبکه، Boost.FileSystem برای کار با سیستم‌فایل و Boost.DateTime برای کار با زمان و تاریخ مورد استفاده قرار می‌گیرد. با استفاده از این ابزارها، می‌توانید برنامه‌های کاربردی پیچیده را با قابلیت‌های خاص و منحصربه‌فرد طراحی و پیاده‌سازی کنید.

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

    ج. توسعهٔ بازی‌ها و گرافیک کامپیوتری
    Boost در زمینهٔ توسعهٔ بازی‌ها و گرافیک کامپیوتری نیز استفاده می‌شود. ابزارهایی مانند Boost.Geometry برای کار با هندسه و Boost.Graph برای تحلیل و پردازش گراف‌ها مورد استفاده قرار می‌گیرند. این ابزارها به توسعه‌دهندگان کمک می‌کنند تا الگوریتم‌های پیچیده را برای بازی‌ها و سیستم‌های گرافیکی پیاده‌سازی کنند و تجربهٔ کاربری بهتری را ارائه دهند.

    ۶.اهمیت کتابخانهٔ Boost

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

    ۷. چگونه از کتابخانهٔ Boost بهره‌برداری کنیم؟

    برای بهره‌برداری از کتابخانهٔ Boost و استفاده بهینه از قابلیت‌های آن، می‌توانید مراحل زیر را دنبال کنید:

    الف. نصب کتابخانه
    ابتدا باید کتابخانهٔ Boost را بر روی سیستم خود نصب کنید. می‌توانید نسخهٔ مناسب برای سیستم‌عامل خود را از وبسایت رسمی Boost دریافت کنید و طبق دستورالعمل‌های نصب آن را انجام دهید.

    ب. مستندات و منابع آموزشی
    بهتر است پیش از شروع استفاده از Boost، به مستندات رسمی آن مراجعه کنید. مستندات کتابخانه به شما راهنمایی دقیقی دربارهٔ ویژگی‌ها، توابع و کلاس‌های موجود در Boost ارائه می‌دهد. همچنین، می‌توانید از منابع آموزشی آنلاین و کتاب‌های مرجع موجود برای یادگیری عمیق‌تر از Boost استفاده کنید.

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

    ۸. بهترین استفاده از کتابخانهٔ Boost

    برای بهترین استفاده از کتابخانهٔ Boost، توصیه می‌شود:

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

    نتیجه‌گیری

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

    نقل قول

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

     


  3. با سلام و درود‌های فراوان بر شما دوست‌داران طراحی و توسعه،

    امروز نیاز دیدم یک توضیح در رابطه با تفاوت‌های عمدهٔ فناوری ساخت و توسعهٔ رابط‌کاربری در نرم‌افزار‌های تحت فریمورک کیوت ارائه کنم. در این مقاله من به دو سبک متفاوت با کارآیی و اهمیت آن‌ها مطابق با مستندات فریم‌ورک کیوت می‌پردازم و شما می‌توانید بر اساس نیازمندی و برداشت خود از آن، یکی از فناوری‌های لازم را انتخاب و ظاهر برنامهٔ خودتان را با آن آراسته کنید!

    رابط‌کاربری (UI) یکی از عوامل اصلی در جذب کاربران و بهبود تجربه‌‌کاربری (UX) است. یک طراحی صحیح و مناسب برای واسط‌کاربری می‌تواند کاربران را به نرم‌افزار شما جذب کند و به معنای واقعی کاربران را متقاعد کند که نرم‌افزار شما صحیح است و قابل استفاده، حتی اگر امر اصلی برنامه اجرای آن باشد. رابط‌کاربری مناسب، کاربران را به یادگیری آسان فرایند‌های نرم‌افزار و همچنین استفاده از آن ترغیب می‌کند. با طراحی یک واسط کاربری ساده و کاربر پسند، می‌توان زمان و هزینه‌ای برای آموزش کاربرانی که قرار است از نرم‌افزار شما استفاده کنند, صرفه جویی کرد.

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

    نقل قول

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

    اهمیت رابط‌های کاربری مدرن و سنتی

    رابط‌کاربری سنتی، یک رابط‌کاربری ابتدائی است، که چندین دهه است به کار می‌رود. این سبک برای محیط‌های کاربردی نسبتاً پایدار و ساده‌تر معرفی شده است، با پنجره‌ها، دستورالعمل‌های پایه، معمول و منو‌‌های کلاسیک. اما اخیراً، رابط‌های کاربری مدرن، تلاش کرده‌اند تا به کاربرانی که حوصله‌ٔ کار با رابط‌کاربری سنتی را ندارند، ارائه شوند چرا که نیاز به تعامل و تجربه‌کاری بهتر بیشتر و بیشتر می‌شود. این رابط‌ها، با استفاده از طراحی مدرن، صفحات پویا، و مفهوم سرعت، زیبایی و حتی تحرک مناسب، می‌خواهند توانایی شما را در مدیریت محیط‌کاری (کار با نرم‌افزار) افزایش دهند. بیشتر رابط‌های کاربری مدرن، به کاربران محیط کاری تمیز و منظم، صفحه اصلی متحرک، آیکون های جذاب و فهرست منوی منظم، نوع قلم و اندازهٔ مناسب و جذاب را ارائه می‌دهد تا با اشتیاق بیشتری از کار با محیط مورد نظر لذت ببرید.

    designer-multiple-screenshot.png

    preui.jpg

    در این سند، تفاوت بین Widgets Qt و Qt Quick و نحوهٔ انتخاب مناسب برای نیازهای برنامه خود را توضیح خواهیم داد. قبل از اینکه به دلایلی بپردازیم که چرا شما ممکن است بخواهید Widgets Qt را به Qt Quick یا برعکس انتخاب کنید، سپس شروع به بررسی آنچه که هر کدام دقیقاً ارائه می‌دهند و در چه شرایطی می‌توانید از آنها استفاده کنید نیز خواهیم داشت.

    راه‌کار‌های فریم‌ورک Qt برای طراحی رابط‌کاربری

    این فریم‌ورک دارای چندین فناوری برای ایجاد رابط‌کاربری است. در حالی که می‌توان این فناوری‌های مختلف را در صورت نیاز ترکیب و مطابقت داد، یک رویکرد اغلب برای نوع خاصی از رابط کاربری مناسب‌تر از سایرین است. Qt Creator مثال خوبی از برنامه‌ای است که ویجت‌های سنتی Qt را با Qt Quick ترکیب می‌کند. Qt Widgets اساس رابط‌کاربری را تشکیل می‌دهند، در حالی که Qt Quick به عنوان مثال برای اجرای حالت خوش آمدگویی استفاده می شود. بخش‌های زیر معرفی مختصری از فناوری‌های موجود برای ایجاد رابط کاربری و جدول مقایسه‌ای برای کمک به انتخاب بهترین فناوری مناسب ارائه می‌دهند.

    دربارهٔ Qt Widget (کیوت ویجت)

    ماژول Qt Widgets مجموعه‌ای از عناصر رابط‌کاربری را برای ایجاد رابط‌های کاربری کلاسیک به سبکِ پیش‌فرضِ دسکتاپ فراهم می‌کند. کلاس QWidget قابلیت اولیه برای رندر کردن (ساخت) روی صفحه و مدیریت رویدادهای ورودی کاربر را فراهم می‌کند. تمام عناصر UI که Qt ارائه می‌کند یا زیر کلاس‌های QWidget هستند یا در ارتباط با یک زیر کلاس QWidget استفاده می‌شوند. ایجاد ویجت‌های سفارشی با زیر کلاس QWidget یا یک زیر کلاس مناسب و پیاده‌سازی مجدد کنترل کننده رویداد مجازی انجام می‌شود.

    parent-child-widgets.png

    نقل قول

    ویجت‌ها عناصر اصلی برای ایجاد رابط‌کاربری در Qt هستند. ویجت‌ها می‌توانند داده‌ها و اطلاعات وضعیت را نمایش دهند، ورودی کاربر را دریافت کنند، و محفظه‌ای برای سایر ویجت‌ها و کنتل‌ها فراهم کنند که باید با هم گروه‌بندی شوند.

    سبک‌ها (پوسته‌ها/ظاهر)

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

    windowsvista-tabwidget.png fusion-tabwidget.png macos-tabwidget.png

    به طور کلی، Qt Style Sheets مکانیزم قدرتمندی است که به شما امکان می‌دهد ظاهر ویجت‌ها را سفارشی کنید، علاوه بر آنچه که قبلاً با زیر کلاس‌بندی QStyle امکان‌پذیر است.

    لایه‌بندی‌ها (چیدمان)

    چیدمان‌ها روشی ظریف و انعطاف پذیر برای مرتب کردن خودکار ویجت های کودک در ظرف خود هستند. هر ویجت مورد نیاز اندازه خود را از طریق خصوصیات sizeHint و sizePolicy به چیدمان گزارش می‌دهد و طرح‌بندی فضای موجود را بر این اساس توزیع می‌کند.

    qgridlayout-with-5-children.png qformlayout-with-6-children.png

    محیط Qt Designer یک ابزار قدرتمند برای ایجاد تعاملی و چیدمان ویجت‌ها در طرح‌بندی است.

    کلاس‌های Model/View

    معماری model/view کلاس‌هایی را ارائه می‌دهد که نحوه ارائه داده‌ها به کاربر را مدیریت می‌کنند. برنامه‌های مبتنی بر داده که از فهرست‌ها و جداول استفاده می‌کنند، به گونه‌ای ساختار یافته‌اند که داده‌ها و مشاهده را با استفاده از مدل‌ها، نماها و نمایندگان جدا کنند.

    windows-treeview.png

    محیط توسعهٔ Qt Creator و بخش Qt Designer

    ویرایشگر کد پیشرفته Qt Creator به شما امکان می‌دهد نرم‌افزار را به زبان‌های C++، QML، جاوا اسکریپت، پایتون و سایر زبان‌ها بنویسید. این ویژگی تکمیل کد، برجسته سازی نحو، refactoring است و دارای اسناد داخلی در نوک انگشتان شما است.

    qtcreator_formeditor_1920.jpg

    دربارهٔ کیوت کوئیک (Qt Quick)

    ماژول Qt Quick کتابخانهٔ استاندارد برای نوشتن برنامه‌‌های کاربردی QML است. در حالی که ماژول Qt QML موتور QML و زیرساخت زبان را فراهم می‌کند، ماژول Qt Quick تمام انواع اساسی لازم برای ایجاد رابط‌کاربری با QML را ارائه می‌دهد. در واقع یک بوم بصری را ارائه می‌کند و شامل انواعی برای ایجاد و متحرک کردن اجزای بصری، دریافت ورودی کاربر، ایجاد مدل‌ها و نماهای داده‌ها و نمونه‌سازی با تأخیر شیء است.

    qtquickcontrols2-styles.png

    ماژول Qt Quick نیز یک API QML ارائه می‌کند که انواع QML را برای ایجاد رابط‌های کاربری با زبان QML فراهم می‌کند و هم یک رابط‌برنامه‌نویسی (API) از ++C برای گسترش برنامه‌های QML با کد ++C ارائه می‌کند. این یک مزیت بزرگ است که به شما اجازه می‌دهد رابط‌های مبتنی بر قدرت سی++ را به خوبی ارائه کنید.

    پوستهٔ پیش‌فرض (Default) تا کیوت ۵ و پوستهٔ پایه (Basic) از کیوت ۶ به بعد.

    qtquickcontrols-basic.png

    سبک پیش فرض یک سبک همه جانبه ساده و سَبُک است که حداکثر عملکرد را برای کنترل های سریع Qt ارائه می دهد.

     

    نقل قول

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

    پوستهٔ فیوژن (Fusion)

    qtquickcontrols-fusion-light.png qtquickcontrols-fusion-dark.png

    سبک Fusion یک سبک پلتفرم آگنوستیک است که ظاهری بی‌نظیر دسک‌تاپ را برای کنترل‌های کیوت کوئیک ارائه می‌دهد.

    پوستهٔ ایمَجین (Imagine)

    qtquickcontrols-imagine.png

    سبک Imagine بر اساس دارایی‌های تصویر است. این سبک دارای مجموعه‌ای پیش‌فرض از تصاویر است که به راحتی با ارائه یک فهرست حاوی تصاویر با استفاده از یک قرارداد نامگذاری از پیش تعریف شده قابل تغییر است.

    پوستهٔ مک‌او‌اِس (macOS) از کیوت ۶ به بعد.

    qtquickcontrols-macos-light.png qtquickcontrols-macos-dark.png

    سبک macOS یک سبک بومی برای macOS است.

    پوستهٔ آی‌او‌اِس (iOS) از کیوت ۶ به بعد.

    qtquickcontrols-ios-light.png qtquickcontrols-ios-dark.png

    سبک iOS یک سبک بومی برای iOS است.

    نقل قول

    توجه: این سبک فقط برای برنامه‌هایی که در iOS اجرا می‌شوند در دسترس است.

    پوستهٔ متریال (Material)

    qtquickcontrols-material-light.png qtquickcontrols-material-dark.png

    سبک Material،  طراحی جذابی را بر اساس دستورالعمل‌های طراحی متریال Google ارائه می‌کند، اما به منابع سیستم بیشتری نسبت به سبک پیش‌فرض نیاز دارد.

    پوستهٔ یونیورسال (Universal)

    qtquickcontrols-universal-light.png qtquickcontrols-universal-dark.png

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

    پوستهٔ ویندوز (Windows) از کیوت ۶ به بعد.

    qtquickcontrols-windows.png

    سبک Windows یک سبک بومی برای Windows است.

    نقل قول

    توجه: این سبک فقط برای برنامه های در حال اجرا در ویندوز موجود است.

    اگر هیچ سبکی به صراحت تنظیم نشده باشد، یک سبک پیش فرض استفاده خواهد شد. سبکی که استفاده می‌شود به سیستم‌عامل بستگی دارد:

    • سیستم‌عامل اندروید: Material Style
    • سیستم‌عامل آی‌او‌اِس: iOS Style
    • سیستم‌عامل لینوکس: Fusion Style
    • سیستم‌عامل مک‌او‌اِس: macOS Style
    • سیستم‌عامل ویندوز: Windows Style

    انتخاب سبک در زمان کامپایل

    انتخاب سبک زمان کامپایل راهی برای تعیین یک سبک برای استفاده با وارد کردن آن در QML است. به عنوان مثال، برای وارد کردن سبک Material:

    import QtQuick.Controls.Material
    
    ApplicationWindow {
        // ...
    }

    انتخاب سبک در زمان اجرا

    انتخاب سبک زمان اجرا راهی برای تعیین یک سبک برای استفاده با وارد کردن QtQuick.Controls است:

    import QtQuick.Controls

    افزونهٔ QtQuick.Controls استایل و استایل بازگشتی را که در زمان اجرا تنظیم شده‌اند از طریق یکی از روش‌های زیر وارد می‌کند:

    • دستورQQuickStyle::setStyle()
    • The -style آرگومان خط فرمات
    • QT_QUICK_CONTROLS_STYLE متغیر‌های محای
    • qtquickcontrols2.conf پیکربندی از طریف فایل

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

    برای اجرای یک برنامه با یک سبک خاص، یا با استفاده از QQuickStyle در ++C، پوسته را پیکربندی کنید، یک آرگومان خط فرمان را ارسال کنید، یا یک متغیر محیطی را تنظیم کنید. روش دیگر، سبک ترجیحی و ویژگی‌های خاص سبک را می‌توان در یک فایل پیکربندی مشخص کرد.

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

    استفاده از Qt Quick Style در ++C

     رابط‌های QQuickStyle C++ API پیکربندی یک سبک خاص را ارائه می‌کند. مثال زیر یک برنامه Qt Quick Controls را با سبک Material اجرا می‌کند:

    QQuickStyle::setStyle("Material");

    استفاده از روش آرگومان‌های خط فرمان

    ارسال آرگومان خط فرمان-style راه مناسبی برای آزمایش سبک‌های مختلف است. این روش بر سایر روش های ذکر شده در زیر ارجحیت دارد. مثال زیر یک برنامه Qt Quick Controls را با سبک Material اجرا می‌کند:

    ./app -style material

    استفاده از روش متغیر‌های محیطی

    تنظیم متغیر محیطی QT_QUICK_CONTROLS_STYLE را می‌توان برای تنظیم ترجیح سبک در سراسر سیستم استفاده کرد که بر فایل پیکربندی ذکر شده در زیر ارجحیت دارد. مثال زیر یک برنامه Qt Quick Controls را با سبک جهانی اجرا می‌کند:

    QT_QUICK_CONTROLS_STYLE=universal ./app

    استفاده از روش پیکربندی فایل

    کنترل‌های کیوت کوئیک، از یک فایل پیکربندی خاص پشتیبانی می‌کند، :/qtquickcontrols2.conf، که در منابع یک برنامه تعبیه شده است.

    فایل پیکربندی می‌تواند سبک ترجیحی (ممکن است با یکی از روش‌هایی که قبلا توضیح داده شد لغو شود) و ویژگی‌های خاص سبک را مشخص کند. مثال زیر مشخص می کند که سبک ترجیحی سبک Material است.

    [Controls]
    Style=Material

    سفارشی‌سازی کنترل‌های کیوت کوئیک

    کنترل کیوت کوئیک از یک سلسله مراتب (درخت) از آیتم‌ها تشکیل شده است. به منظور ارائه ظاهر و احساس سفارشی، پیاده‌سازی پیش‌فرض QML هر آیتم را می‌توان با یک سفارشی جایگزین کرد.

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

     

    پشتیبانی از High-DPI در کیوت کوئیک

    کنترل‌های کیوت کوئیک، از مقیاس‌گذاری چند-سکویی با DPI (نقطه در اینچ) بالا که در Qt 5.6 معرفی شده است، پشتیبانی می‌کند. این ویژگی انتخابی است و می‌توان آن را با تنظیم ویژگی برنامه Qt::AA_EnableHighDpiScaling در ++C قبل از ساخت QGuiApplication فعال کرد:

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    
    int main(int argc, char *argv[])
    {
        QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // <--
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        return app.exec();
    }

    محیط طراحی اختصاصی Qt Design Studio

    • فرآیند توسعه خود را با پر کردن شکاف بین طراحان و توسعه‌دهندگان متحول کنید تا دیدگاه‌های طراحی خود را به رابط های کاربری آماده تولید تبدیل کنید.
    • طراحی‌های رابط‌کاربری را با ابزارهای طراحی مانند Figma، Adobe XD یا Adobe Photoshop ایجاد کنید. آنها را به استودیوی طراحی Qt وارد کنید، جایی که کد به طور خودکار تولید شده و آماده استفاده توسط توسعه‌دهندگان است.
    • تعاملات و رفتارهای پویا را شبیه‌سازی و تایید کنید. هر چیزی که در استودیوی طراحی Qt ساخته شده است ذاتاً کراس پلتفرم است و می‌تواند در هر سخت‌افزار یا محیط سیستم‌عاملی کامپایل شود.

    QTDS_LandingPage_01.jpg

     

    وقتی در مورد ایجاد رابط‌کاربری صحبت می‌کنیم، فقط در مورد ایجاد یک ماکت با دارایی‌های موجود صحبت نمی‌کنیم. با Qt Design Studio، دارایی‌های شما تبدیل به یک ترکیب رابط‌کاربری می‌شود که آماده عملکرد است.

    تفاوت‌های عمدهٔ Qt Widgets

    • طراحی با این ماژول فقط بر پایهٔ زبان‌های برنامه‌نویسی ++C و Python در امکان‌پذیر است.
    • .سبک و ظاهر بومی در پلتفرم‌های دسکتاپ
      • اما نه در پلتفرم‌های موبایل.
      • امکان سفارشی شدن را دارد.
    • به بک‌اند بومی جهت ساخت نیاز ندارد.
      • می‌تواند در مواقع لزوم از رابط‌های برنامه‌نویسی بومی بک‌اندی هر پلتفرم استفاده کند.
    • سبک پایه را ارائه می‌کند، روان نیست، اما امکان تعریف انیمیشن را ارائه می‌کند.
    • به واسطهٔ زیر کلاس‌ها یا کلاس‌های سفارشی خودتان می‌توانید رفتار‌های ویجت‌ را باز تعریف کنید.
    • محیط اختصاصی طراحی و توسعهٔ Qt Designer

    تفاوت‌های عمدهٔ Qt Quick

    • طراحی با این ماژول به صورت پایه به واسطهٔ QML امکان‌پذیر است.
      • هرچند هنوز هم برخی از نیازمندی‌ها به واسطهٔ ++C و Python انجام می‌شود.
      • شما می‌توانید ماژول‌ها و کامپوننت‌های سفارشی خوبی به واسطهٔ ++C برای QML طراحی کنید.
    • ظاهر کاربری بومی تحت ماژول Qt Quick Controls از نسل کیوت ۶ به بعد ممکن شده است.
    • تطبیق و دریافت اطلاعات پوسته برای اندروید در زمان نیاز ممکن است.
    • به بک‌اند بومی و پس‌زمینه وابسته است.
      • همچنین می‌توانید ایتم‌های خود را به صورت مستقیم با بک‌اند بومی ارائه کنید.
    • می‌توانید پوستهٔ روان و جذابی را تعریف کنید.
      • پیاده‌سازی انیمیشن‌ها و جلوه‌های بصری پیچیده بسیار ساده قابل پیاده‌سازی شدن است.
      • جلوه‌های گرافیکی به راحتی قابل تعریف هستند.
    • امکان سفارشی‌سازی رفتار‌های آیتم و کنترل‌ها وجود دارد.
      • به واسطهٔ گسترش و یا ساخت کامپوننت‌های سفارشی خود بر اساس انواع موجود در Qt Quick.
    • علاوه بر پشتیبانی از محیط Qt Designer، به محیط اختصاصی و پیشرفتهٔ طراحی و توسعهٔ Qt Design Studio مجهز است.

    چه زمانی باید یکی از این فناوری‌ها را به دیگری ترجیح دهیم؟

    • Qt Widgets
      • اگر شما نیاز به یک رابط‌کاربری ساده و سریع نیاز دارید.
      • اگر نمی‌خواهید با JavaScript سرو کار داشته باشید.
    • Qt Quick
      • زمانی که می‌خواهید رابط‌های کاربری جذاب و خلاقانه تولید کنید.
      • زمانی که می‌خواهید برنامهٔ خود را برای موبایل و دستگاه‌های جاسازی شده (امبد) ارائه کنید.
      • وقتی هدفتان ساخت نرم‌افزار‌های چند-سکویی باشد.
      • زمانی که می‌خواهید بیشترین جذابیت و کارآیی را از نظر UI و UX ارائه کنید.

    آشنایی با زیرساخت RHI و کارآیی دو فناوری کیوت ویجت و کیوت کوئیک

    بسیاری از کاربران با توجه به کد‌های سی++ در کیوت ویجت، بر این باورند که ساخت و توسعهٔ رابط‌های کاربری با Qt Widgets عموماً سریع‌تر و از کارآیی بهتری برخوردار است. این حقیقت در قبل از زمان فناوری جدید از نسل کیوت کوئیک اعتبار بسیاری داشت، اما با توجه به توسعهٔ زیرساخت‌های کیوت در نسل‌های ۵.۱۵ و ۶ به بعد، تمامی فرایند رندرینگ به لطف کد‌های سی‌پلاس‌پلاس به صورت بومی تحت معماری RHI انجام می‌شوند و این مسأله دیگر حائز اهمیت نیست، مگر این‌که دلایل شما برای انتخاب کیوت ویجت صرفاً دسترسی ساخت به رابط‌کاربری ساده‌تر و عدم اهمیت داشتن سبکِ نوین باشد.

    rhiarch-3.png

    زیرساخت QRhi، یک رابط سخت‌افزاری رندر Qt، انتزاع گرافیکی داخلی Qt است که در آن API‌های سه بعدی مانند OpenGL، Vulkan، Metal و Direct 3D درگیر هستند. در مقایسه با 5.15، پیشرفت‌های اصلی در نسخه 6.0، اصلاحات پولیش زیاد اینجا و آنجا و مهمتر از همه، مجموعه بزرگی از بهینه‌سازی عملکرد است. این بهینه سازی به طور کامل به صورت بومی و رابط‌های برنامه‌نویسی ترکیبی با ++C پیاده‌سازی شده است و کارآیی خروجی در تولید رابط‌های خلاقانه، جلوه‌های بصری ۲ و ۳ بعدی بسیار عالی خواهد بود.

     

    سخن پایانی

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

    نقل قول

    اگر این مقاله برای شما مفید بود، آن را با دوستان خود به اشتراک بگذارید.

     


  4. جزئیات، به‌روز رسانی‌ها و ویژگی‌های C++20

    معرفی و نمونه کد‌های کلاس std::span

    کلاس std::span یک کلاس در C++20 است که برای نشان دادن (نمایش ظاهری) یک محدوده دنباله‌ای از اشیاء پیوسته بکار می‌رود. الگوی کلاس span یک شیء را توصیف می‌کند که می‌تواند به یک دنباله متوالی از اشیاء با اولین عنصر دنباله در موقعیت صفر ارجاع دهد. یک span می‌تواند دارای دامنه‌ی استاتیک باشد، در این صورت تعداد عناصر در دنباله در زمان کامپایل مشخص است و در نوع خودشان رمزگذاری شده‌اند و یا دامنه‌ی داینامیک دارد. اگر یک span دارای دامنه‌ٔ داینامیک باشد، به طور معمول، پیاده‌سازی آن شامل دو عضو است: یک اشاره‌گر به T و یک اندازه است. یک span با دامنه‌ٔ استاتیک ممکن است فقط یک عضو داشته باشد: یک اشاره‌گر به T.

    template<
        class T,
        std::size_t Extent = std::dynamic_extent
    > class span;

    برای استفاده از کلاس std::span، باید ابتدا کتابخانه <span> را به کدتان اضافه کنید. سپس برای ایجاد یک شیء از این کلاس، می‌توانید از یک اشاره‌گر به شروع دنباله و طول آن استفاده کنید. برای مثال: 

    #include <span>
    #include <iostream>
    
    int main() {
        int arr[] = {1, 2, 3, 4, 5};
        std::span<int> mySpan(arr, 5);
        
        for (int i : mySpan) {
            std::cout << i << " ";
        }
        
        return 0;
    }

    در این مثال، یک آرایه از نوع int با ۵ عضو تعریف شده و سپس یک شیء از کلاس std::span با استفاده از این آرایه و طول آن ایجاد می‌شود. سپس با استفاده از حلقه for، اعضای دنباله در خروجی چاپ می‌شوند.

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

    اینجا یک نمونه از استفاده از std::span در یک کد C++20 آورده شده است:

    #include <iostream>
    #include <span>
    
    int main() {
        int arr[] = {1, 2, 3, 4, 5};
    
        std::span<int, 5> s(arr); // s refers to the whole array
    
        for (auto& elem : s) { // range-based for loop
            std::cout << elem << ' ';
        }
        std::cout << '\n';
        
        std::span<int, 3> s2(arr + 1, 3); // s2 refers to {2, 3, 4}
    
        for (auto& elem : s2) {
            std::cout << elem << ' ';
        }
        std::cout << '\n';
    }
    

    در این کد، یک آرایه از 5 عدد تعریف شده است. سپس با استفاده از std::span، دو نمونه برای این آرایه تعریف شده است. پس از آن ، با استفاده از حلقه for ، مقادیر در هر دو نمونه std::span به ترتیب چاپ شده و تفاوت بین آن‌ها نیز نشان داده شده است.

    برخی از مزایای این کلاس به صورت زیر است:

    • کد مطمئن‌تر: به دلیل استفاده از نمای مناسبی از ارث‌بری، این کلاس امکان بازنویسی کد و تجدید نظر در طراحی را فراهم می‌کند.
    • کاربردهای متعدد: توانایی نشان دادن داده‌های پیوسته با هر نوع، دنباله‌های داخلی و خارجی، بردارها، ماتریس‌ها و موارد دیگر، std::span را به یک وسیله کارآمد در برنامه‌نویسی ترکیب‌شدها و هم‌زمان‌سازی داده‌ها تبدیل کرده است.
    • عملکرد بهتر: به دلیل این که std::span یک کلاس ساده به همراه تعریف مجددی از iterator (https://en.cppreference.com/w/cpp/iterator) هاست، عملیاتی مانند خواندن، نوشتن و مرتب سازی داده‌ها، بسیار سریعتر از زیربرنامه‌های برنامه سازی بهینه شده است.
    • پشتیبانی از تشخیص خطا: با استفاده از std::span، می‌توان یک شیء معتبری ایجاد کرد که در آن تغییرات اندیس باید در محدوده معتبر واقع شود که باعث بهبود تشخیص خطا در کد می‌شود.

    اینجا یک نمونه کد ورودی با std::span برای محاسبه میانگین اعداد یک محدوده از داده هاست که توضیحات کد نیز در کد ذکر شده است:

    #include <iostream>
    #include <span>
    #include <algorithm>
    
    double average(std::span<int> ns)
    {
        if (ns.empty())
            throw std::invalid_argument("empty span");
        if (ns.size() > static_cast<size_t>(std::numeric_limits<int>::max()))
            throw std::invalid_argument("span size exceeds int max");
        if (std::any_of(ns.begin(), ns.end(), [](const int& n) { return n < 0; }))
            throw std::invalid_argument("span contains negative values");
        return static_cast<double>(std::accumulate(ns.begin(), ns.end(), 0)) / ns.size();
    }
    
    int main()
    {
        int arr[] = { 1, 2, 3, 4, 5 };
        std::span<int> span_arr(arr, 5);
        try {
            std::cout << average(span_arr) << '\n';
        } catch(const std::exception& ex) {
            std::cerr << "Error: " << ex.what() << '\n';
        }
        return 0;
    }

     

    در کد زیر، یک std::span از یک آرایه از اعداد پشت سر هم ایجاد شده است و سپس به عنوان ورودی به تابع calculate_mean() منتقل شده است. تابع calculate_mean() به صورت یک حلقه که به ازای عنصری که به عنوان ورودی دریافت می کند، محدوده داده ها را پیمایش می کند و میانگین اعداد را محاسبه می کند.  با استفاده این تابع و تعریف یک آرایه از اعداد، برنامه قادر است میانگین اعداد را محاسبه کند.

    #include <iostream>
    #include <span>
    
    double calculate_mean(std::span<double> nums)
    {
        double sum = 0.0;
        for (auto num : nums) {
            sum += num;
        }
        return sum / static_cast<double>(nums.size());
    }
    
    int main()
    {
        double nums[] = {2.0, 3.0, 5.0, 7.0, 11.0, 13.0};
        std::span<double> nums_span(nums, std::size(nums));
        double mean = calculate_mean(nums_span);
        std::cout << "mean = " << mean << std::endl;
    
        return 0;
    }
    

    کاربرد std::span در ورودی توابع

    یکی از استفاده های مهم std::span ، به عنوان ورودی تابع است. با استفاده از std::span به عنوان ورودی، می توان به سادگی یک محدوده از داده ها را به یک تابع انتقال داد و از انتقال داده های اضافی و همچنین رعایت روشن بودن کد استفاده کرد. 

    با استفاده از std::span به عنوان ورودی تابع، عملیات از هر نوع می تواند مستقل از نوع داده های کانتینر باشد و به همین دلیل کد تمیز تر و بیشتر چند منظوره خواهد بود.

    #include <iostream>
    #include <span>
    
    double calculateAverage(std::span<double> nums) {
        double sum = 0;
        for (auto num : nums) {
            sum += num;
        }
        return (nums.size() > 0) ? sum / nums.size() : 0;
    }
    
    int main() {
        double data[] = {2.5, 3.8, 4.2, 1.7, 6.5};
        double average = calculateAverage(data);
    
        std::cout << "Average: " << average << std::endl;
    
        return 0;
    }

    در این کد، تابع calculateAverage یک std::span از نوع double به عنوان ورودی دریافت می کند و با استفاده از آن، میانگین عناصر را محاسبه می کند. سپس در تابع main یک آرایه از اعداد اولیه تعریف شده است که به عنوان ورودی به تابع calculateAverage ارسال می شود و سپس میانگین محاسبه شده چاپ می شود.

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

     

    کاربرد std::span در کلاس‌ها

    استفاده از std::span در کلاس ها، می تواند در طراحی کلاس هایی که بر روی داده هایی فیکس‌شده کار می کنند، مفید باشد. این کار به تشخیص و جلوگیری از خطرات مربوط به ارجاع به اشاره یا نشانگر اشاره که به محدوده ای خارج از داده های کلاس مستقر شده اند، کمک می کند. 

    #include <span>
    
    class DataProcessor {
    private:
      std::span<const int> data;
    public:
      explicit DataProcessor(std::span<const int> d) : data(d) {}
      double calculateMean() const {
        double sum = 0.0;
        for (auto num : data) {
          sum += num;
        }
        return sum / static_cast<double>(data.size());
      }
    };

    همچنین، می‌توان با تعریف تابع‌هایی که با std::span کار می کنند، از صرفه جویی در حجم کدها خود لذت برد.

    اینجا یک نمونه کد با استفاده از std::span در طراحی یک کلاس برای مدیریت یک آرایه با سایز ثابت است:

    #include <array>
    #include <span>
    
    template <typename T, std::size_t N>
    class FixedArray {
    public:
        FixedArray(std::array<T, N>& arr) : data(arr), memory(data) { }
    
        std::span<T, N> memory;
    
    private:
        std::array<T, N>& data;
    };

    در این کد، FixedArray یک کلاس است که یک آرایه با سایز ثابت را مدیریت می‌کند. با استفاده از std::span، ما می‌توانیم برای نگهداری داده‌ها از حافظه‌ای استفاده کنیم که قبل تر allocated شده است (در اینجا داده‌ها از آرایه data استخراج شده و به صورت پویایی در memory نگهداری می‌شوند). به این ترتیب، ما از خطرات ارجاع به اشاره به محدوده‌های خارج از داده ها به دلیل دستکاری در آرایه، محافظت می‌کنیم.

    • پسندیدن 1

  5. در 5 دقیقه قبل، sanatnegar گفته است :

    ابزار Andrioid SDK , Android NDK, openssl , commandlinetools و غیره رو نصب کردم و در قسمت devices همه تیک ها سبز هست. یک پروژه qtquick برای اندروید ایجاد کردم. موقع کامپایل با خطای (gradle) زیر مواجه میشم 

    General error during conversion: Unsupported class file major version 63

    از JDK ورژنن 17 تا 20 رو هم امتحان کردم بازم فایده نداشت

    علیکم سلام،

    طبق این دو آموزش پیش برید.

    پیکربندی فریم‌ورک کیوت برای پلتفرم اندروید

    پیکربندی و به‌روز‌ رسانی کیوت ۶.۴ برای اندروید ۱۳

    • پسندیدن 1

  6. در 9 ساعت قبل، rezaict گفته است :

    سلام، واقعیتش تا الان درگیرش بودم ولی به نتیجه ای نرسیدم و نتونستم کد رو بزنم فک کنم چون من تازه وارد این حوزه شدم و مفاهیم رو به طور کامل بلد نیستم این اتفاق برام افتاده

    به هر حال ممنون از شما که برام وقت گذاشتین

    سپاسگزارم

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

    موفق باشید.


  7. به نظرم به خاطر تبدیل مجدد به double هست، خب شما خروجی مستقیم از کتابخانه رو چاپ کنید و در قالب Text به کنترل QLabel بدین.

    یک مثال ساده:

    BigInt big1 = 123456789;
    BigInt big2 = 987654321;
    BigInt res = big1 * big2;
    qDebug() << res.to_string().c_str();
    ui->label->setText(res.to_string().c_str());

     


  8. در 2 ساعت قبل، rezaict گفته است :

    ممنونم از پاسختون

    جسارتا موقعی که اجراش میکنم با ارور مواجه میشم (من دارم از حالت widget application در QT استفاده میکنم. شاید به خاطر این باشه که از حالت console استفاده نمیکنم)

     

    error: multiple definition of `is_valid_number(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
    debug/calculator.o: In function `ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE16_M_construct_auxIPcEEvT_S7_St12__false_type':

    بنده روی Qt Widget و STL آزمایش کردم، مشکلی نداره و اجرا می‌شه.

    خطایی که ارسال کردین اشاره به باز‌تعریف is_valid_number داره، بررسی کنید که تکرار در تعریف تابع وجود نداشته باشه.


  9. در 17 ساعت قبل، rezaict گفته است :

    سلام. اگر بخوایم برای ضرب دو عدد با طول بی نهایت در یک ماشین حساب که در محیط QT ساخته شده است به شرطی که نتیجه ضرب را نشان دهد و overflow رخ ندهد، از چه کتاب خانه ای می توان استفاده کرد؟

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

    #include "BigInt.hpp"
    /////
    
    
    BigInt big1 = 1234567890, big2;
    big2 = "9876543210123456789098765432101234567890";
    
    std::cout << big1 * big2 * 123456 << "\n";
    // Output: 1505331490682966620443288524512589666204282352096057600

     


  10. در 11 ساعت قبل، Hamed123 گفته است :

    سلام، با پیشرفت فناوری های ابری کلی سوال پیش آمده برام، اولین سوال اینه میشه از فناوری ابری برای ذخیره داده های سی پلاس پلاس استفاده کرد؟ 

     

    بنظر شما کدوم پایگاه داده بهتر و امن تر و سریع تره؟

    درود،

    در سی‌پلاس‌پلاس هر نوع پایگاه داده قابل استفاده است.

    برای دسترسی به لیست پایگاه‌های مطرح ابری به این لینک نگاهی بکنید.

     


  11. در 1 ساعت قبل، chikar گفته است :

    سلام

    مثل اینکه این خطا رو برای هر برنامه ای که از کیوت 6 استفاده کرده باشه روی سیستم من که ویندوز 10 است رخ می ده، به عنوان مثال نرم افزار OBS Studio از کیوت 6 استفاده کرده و وقتی من این برنامه رو چه نصب کنم چه از نسخه Portable استفاده کنم همین خطا رو می ده

    This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
    Available platform plugins are: windows.

    وابستگی‌ها یا فریم‌ورک کیوت ۶ به طور صحیح و کامل روی سیستم‌عامل شما نصب نیست.

    به غیر از این دلیل دیگه‌ای نمی‌تونه باشه.


  12. در هم اکنون، cactus گفته است :

    سلام

    ممنون از اینکه پاسخ سوالم رو دادید.
    ولی خیلی گیج کننده هست. آیا راه ساده تری هم وجود داره؟؟

    راه ساده‌ترش این هست که از نسخه‌های GUI دار استفاده کنید.

    https://github.com/topics/qt-deploy

    https://github.com/probonopd/linuxdeployqt

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


  13. در 13 ساعت قبل، cactus گفته است :

    سلام به همه دوستان
    من میخوام برنامه های نوشته شده در محیط Qt Creator رو ، در کامپیوتر دیگه که Qt نصب نیست اجرا کنم.
    لطفا راهنمایی کنید.
    ممنون از تک تک دوستان 

    سلام،

    شما باید برنامه رو به صورت خام خروجی گرفته و تمامی ملزوماتش رو در کنارش قرار بدین، این کار رو اگه حرفه‌ای باشید می‌تونید به صورت دستی انجام بدین و اگر نه می‌تونید از ابزار خود کیوت استفاده کنید که لینک‌هاش رو در ادامه بر اساس نوع سیستم‌عامل ذکر کردم:

    https://github.com/probonopd/linuxdeployqt

    https://doc.qt.io/qt-5/windows-deployment.html

    https://doc.qt.io/qt-6/macos-deployment.html

    برای مثال دستور زیر در ویندوز قابل استفاده است:

    windeployqt --qmldir <path-to-app-qml-files> --plugindir <path> --qmlimport <directory> --release <path-to-app-binary>

     


  14. در 9 ساعت قبل، Ali71321 گفته است :

    سلام وقت بخیر مهندس

    روی یک سیستم دیگه اون هم ویندوز 10 داشت و نسخه Qt creator هم 5.0.3 بود مشکلی نبود

    البته من برای بیلد اندروید و انتخاب نکردم 

    روی لپ تاپ هم که مشکل اصلی ماست من دوباره کیوت و نصب کردم و الان نسخه Qt Creator 6.0.2 هستش(نسخه 5.0.3 با نصب آنلاین نصب نمیشه)

    ولی باز هم همون ارور و میده. ممکنه از سیستم عامل باشه؟

    فکر میکنم دیگه وقتشه عطای ویندوز و به لقائش ببخشیم و کلا مهاجرت کنیم رو لینوکس?

    خب ببینید شما متن پیامِ خطا رو تا ارسال نکنید نمی‌شه راهنمایی کرد ? روی ویندوز هم من مشکلی ندارم ربطی به سیستم‌عامل نداره.

    ولی خب باید سعی کنید جزئیات رو بررسی کنید.


  15. در 12 ساعت قبل، Ali71321 گفته است :

    خیلی ممنون از راهنماییتون

    متاسفانه اوکی نشد

    ایرادی نداره، موارد زیر رو مجدداً بررسی کنید:

    1. نسخهٔ Qt Creator شما حداقل ۵.۰.۳ باشد.
    2. نسخهٔ NDK و SDK شما به ترتیب ۲۱.۴ و ۲۲.۱ باشد.
    3. مطمئن باشید که پوشهٔ android_openssl در مسیر پیش‌فرضی که کیوت کریتور برای شما پیشنهاد می‌کنه ایجاد و محتوای آن موجود باشد.
    4. سپس در تنظیمات پروژه فایل مربوط به CMake کدی که در پست قبلی گفتم نسبتاً به مسیر واقعی آن وارد کنید.
    5. پروژه را بسازید و سعی کنید دوباره امتحان کنید.

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


  16. در 3 ساعت قبل، Ali71321 گفته است :

    سلام

    از کیوت نسخه 5.15.2 استفاده میکنم و سیستم عامل ویندوز 10 هست

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

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

    و نکته ی دیگه این که فایل هایی که اشاره کردید تو کدوم دایرکتوری باید باشه؟

    طبق لینکی که دادم باید پیش برید و یا در قسمت تنظیمات Qt Creator و بخش Device / Android و کلیک برای دانلود OpenSSL را انجام دهید. موارد لازم دریافت و نصب خواهند شد، سپس در بخش تنظیمات پروژه طبق مستندات پیش برید.

    برای مثال در QMake و CMake به صورت زیر:

    android: include(<path/to/android_openssl/openssl.pri)
    
    if (ANDROID)
        include(<path/to/android_openssl/CMakeLists.txt)
    endif()

     


  17. در 11 ساعت قبل، Ali71321 گفته است :

    متاسفانه زمان اجرای برنامه که قراره اطلاعات نقشه رو از osm بگیره یک ERORR به شکل زیر ظاهر میشه :

    qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed

    مطلب قابل قبولی پیدا نکردم متاسفانه

    سلام،

    خب بهتر بود نسخهٔ کیوت و پلتفرم رو هم مشخص می‌کردید.

    به هر حال بدون شک این خطا مربوط به عدم وجود فایل‌های SSL در کتابخانهٔ مربوط به برنامهٔ شماست.

    باید فایل‌های libcrypto_1_1.so و libssl_1_1.so را به آن اضافه کنید.

    جهت پیشنهاد این دستورالعمل را پیگیری کنید: https://github.com/KDAB/android_openssl 


  18. در 31 دقیقه قبل، Ali71321 گفته است :

    ممنون مهندس

    در مورد API با Qt نتوستم مطلب آموزشی پیدا کنم متاسفانه

    در مورد اتصال به Api که خب مشخصه باید از کلاس‌های شبکه استفاده کنید و به ساختار مشخصی مثل Restful وصل بشید.

    در مورد ساختِ خود Api‌ها و وب‌سرویس‌ها هم باز می‌تونید سمت سرور با همین کلاس‌ها وب‌سرویس رو ارائه بدین، معماری و قالب جی‌سان یا امثالش رو تولید کنید.

    اگر هم به دنبال روش ساده‌تری هستید که با کیوت سمت سرور باشه، از Cutelyst هم می‌تونید استفاده کنید.

    • تشکر شده 1
×
×
  • جدید...