رفتن به مطلب
جامعه‌ی برنامه‌نویسان مُدرن ایران
کامبیز اسدزاده

نمونه مثال مُدرن از برقراری ارتباط بین ++C و QML در قالب Contact List

پست های پیشنهاد شده

همانطور که می‌دانید یکی از مباحث شاید به ظاهر پیچیده در کیوت برقراری ارتباط بین سی‌پلاس‌پلاس و کیو‌ام‌اِل باشد. در این پست من تصمیم گرفتم مثالی را در قالب لیست تماس‌ها ایجاد کنم که شاید بعد‌ها توسعه آن ادامه داشته باشد.

فرض کنید قرار است لیستی از تماس‌ها یا کاربران را دریافت و در بخش رابط کاربری خود در قالب یک لیست نمایش دهیم. قبل از هرچیز باید بدانید که برای چنین کاری کلاسی را در سمت بک‌اِند ایجاد کنید. نام این کلاس را در این مثال 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
  }
}

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

Contact-01.png

برای دسترسی به منبع این مثال می‌توانید به گیت‌هاب من در این لینک مراجعه کنید.

نقل قول

دقت کنید که به خاطر آدرس دهی https در تصاویر آواتار نیاز خواهد بود تا فایل‌های libeay32.dll و ssleay32.dll را در کنار فایل اجرایی برنامه‌ی خود داشته باشید. در غیر اینصورت تصاویر مرتبط با پروتکل https بارگذاری نخواهند شد.

 

  • پسندیدن 1

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

سلام ممنون از مطلب مفیدتون
من نیاز دارم که بتونم یک Qimage رو از داخل cpp به سمت qml بفرستم و نمایش بدم امکانش هست یک مثال خیلی ساده در این مورد درون سایت قرار بدین؟

ویرایش شده در توسط سعید معصومی

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر
در هم اکنون، سعید معصومی گفته است :

سلام ممنون از مطلب مفیدتون
من نیاز دارم که بتونم یک Qimage رو از داخل cpp به سمت qml بفرستم و نمایش بدم امکانش هست یک مثال خیلی ساده در این مورد درون سایت قرار بدین؟

چرا از نوع Image در QML استفاده نمی‌کنید؟ در این صورت فقط نیاز دارین آدرس تصاویر رو بهش انتقال بدین.

مثال:

Image {
    source: "pic/avatar.png"
}

 

به اشتراک گذاری این ارسال


لینک به ارسال
به اشتراک گذاری در سایت های دیگر

برای ارسال دیدگاه یک حساب کاربری ایجاد کنید یا وارد حساب خود شوید

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

ایجاد یک حساب کاربری

برای حساب کاربری جدید در سایت ما ثبت نام کنید. عضویت خیلی ساده است !

ثبت نام یک حساب کاربری جدید

ورود به حساب کاربری

دارای حساب کاربری هستید؟ از اینجا وارد شوید

ورود به حساب کاربری

  • کاربران آنلاین در این صفحه   0 کاربر

    هیچ کاربر عضوی،در حال مشاهده این صفحه نیست.

  • مطالب مشابه

    • توسط کامبیز اسدزاده
      آیا این واقعاً امکان‌پذیر است؟
      پاسخ :  بله!
      من می‌دانم که ممکن است این مبحث تحت سی++ بسیار پیچیده و یک کار بیهوده‌ای باشد! اما واقعیت مساله این است که تا چیزی رو خودتون ندیدین و انجامش ندادین با حرف و حدیث بقیه باورش نکنید!
      من قبلاً در مورد اینکه تحت ++C وب‌سایت میشه طراحی کرد یا خیر تحقیقاتی انجام داده بودم، از لحاظ امکان بودنش جواب مثبت بود اما اینکه به راحتی طراحی تحت Php یا دیگر زبان‌های برنامه‌نویسی باشه خیر! خُب طبیعیه چون شما بسیار راحت یه اسکریپت رو می‌نویسی و روی سرور اجراش می‌کنی و سایت شما به خوبی و خوشی بالا میاد!
      ممکن است در همین قسمت از موضوع شما به این نتیجه رسیده باشید که خُب نیازی به ادامه‌ی بحث نداریم! وقتی کار سختیه پس منطقی نیست و شما احتمالاً دیوانه‌ای!!! 😁
      واقعیت جریان این است بر خلاف آن چیزی که تصور کرده‌ایم طراحی وب‌سایت با سی‌پلاس‌پلاس نه تنها بسیار راحت است بلکه بسیار هم جذاب خواهد بود! اما در نگاه اول ممکن است یک سری محدودیت‌هارا داشته باشد که همه‌ی این موارد با کمی تعمل و بررسی قابل حل هستند به قدری که وقتی درگیر این جریان باشید شیفته‌ی آن خواهید شد.
       
      مزایای یک وب‌سایت تحت سی‌پلاس‌پلاس نسبت به دیگر زبان‌های رایج
      سرعت خارق‌العاده و غیر قابل مقایسه با زبان‌های رایج امنیت بهتر کد‌های شما مدیریت ساده‌تر و انعطاف‌پذیری بالا مصرف بسیار بهینه‌ و غیر قابل تصور از منابع سرور دسترسی نامحدود به کتابخانه‌ها عدم محدودیت در دسترسی به برنامه‌نویسی سطح پایین عدم محدودیت در استفاده از توابع سیستم‌عامل عدم محدودیت در مدیریت سیستم و هر ویژگی‌ دیگری که در زبان‌های اسکریپتی اگر به آن نیاز داشته باشید مجبور هستید تا به صورت اکستنشن آن را تحت سی‌پلاس‌پلاس باز نویسی کنید. سیستم راه‌انداز وب‌سرور چگونه است؟
      در هر سروری CGI به شما امکان این را می‌دهد که بتوانید تحت پروتکل‌های استاندارد برنامه‌های تحت وب را اجرا کنید. شما می‌توانید تحت آن و یا موارد دیگری مانند FatCGI و WSGI و دیگر موارد بهینه شده‌ی آن برنامه‌ی تحت وب را بر روی سرور خود اجرا کنید.
       
      طراحی قالب هماهنگی با HTML, JavaScript, Css در سی‌پلاس‌پلاس چگونه خواهد بود؟
      همه‌ی گزینه‌های مربوط به وب را شما بدون هیچ محدودیتی در اختیار خواهید داشت. شما هیچ محدودیتی در استفاده از ویژگی‌های HTML5 یا CSS3 و یا JavaScript و دیگر فریمورک‌ها و کتابخانه‌های کارآمدی چون Angular.JS را نخواهید داشت. بنابراین از نظر طراحی رابط یک وب‌سایت همانند دیگر زبان‌های رایج می‌توانید روی آن حساب کنید.
       
      طراحی هسته و بک‌اِند وب‌سایت چگونه خواهد بود؟
      همانند زبان‌ها و فریمورک‌های رایج تحت وب شما در سی‌پلاس‌پلاس می‌توانید هسته‌ی وب‌سایت یا سیستم وب‌سایت خود را تحت استاندارد سی‌پلاس‌پلاس و هر کتابخانه‌ای که می‌پسندید و یا به آن تسلط دارید پیاده سازی کنید! به شرطی که قابلیت‌های آن کتابخانه پاسخگوی نیاز‌های شما باشد.
      با این حساب شما می‌توانید حتی سیستم مدیریت محتوای (CMS) خود را طراحی کنید! 😧
      بله سیستم مدیریت محتوا تحت سی‌پلاس‌پلاس! کاملاً جدی هستیم 🙂
      قبل از هر چیز یک مزیت بسیار بزرگی که یک CMS تحت سی‌پلاس‌پلاس می‌تواند داشته باشد مصرف بهینه از منابع سرور خواهد بود. برای مثال در یک مقایسه‌ی‌ ساده و آزمایشی نتیجه‌ی بسیار جالبی ارائه شده است.
      همانطور که می‌دانید Wordpress به عنوان یک سیستم مدیریت محتوای (بلاگ) شناخته شده و تحت Php توسعه‌ یافته است. نسخه‌ی سریعتر و بهینه‌تر آن با نام Ghost تحت Node.JS توسعه یافته است که ما نسخه‌ی توسعه‌ یافته‌ی آن را با یک عمل مشابه در C++1z مورد بررسی قرار داده ایم که نتایج آن بسیار جالب است!
      مصرف حافظه‌
      سیستم مدیریت محتوای Jaguar ۳۵۰۰ درخواست در هر ثانیه 3.6 مگابایت سیستم مدیریت محتوای Ghost 100 درخواست در ثانیه 120 مگابایت پشتیبانی از پایگاه‌های داده
      به لطف کتابخانه‌های عظیم سی‌پلاس‌پلاس امکان مدیریت یک وب‌سایت تحت پایگاه‌های داده مختلفی ممکن است. برای مثال تحت Qt شما می‌توانید به رایجترین درایور‌های بانک‌اطلاعاتی دسترسی داشته و سیستم خود را به آن‌ها مجهز کنید.
      نکته: احتمالاً در برنامه‌نویسی با نود جی‌اس و پی‌اچ‌پی شناختی با کتابخانه‌های OpenSSL, Libcurl و موارد این چنینی داشته اید! کتابخانه‌های فوق عضو لیست کتابخانه‌های C و  ++C هستند. بنابراین شما علاوه بر دسترسی مستقیم بر آن‌ها به هزاران و شاید میلیون‌ها کتابخانه در دنیا سی‌پلاس‌پلاس خواهید داشت.
       
      نمونه‌ی اولیه اما شوق‌آور برای اثبات امکان طراحی وب‌سایت تحت سی‌پلاس‌پلاس
      چندی پیش من تصمیم گرفتم تا سیستم وب‌سایتی را تحت Php7 برای یکی از استارت‌آپ‌ها طراحی و پیاده سازی کنم که در این پست به آن اشاره شده است. از آن‌جایی که به لطف کتابخانه‌ی Qt برنامه‌های سمت کاربر را توسط سی‌پلاس‌پلاس پیاده سازی کرده بودم به این فکر افتادم چرا سمت سرور و بخش وب‌سایت هم با آن هماهنگ نشود!؟
      اینگونه هماهنگی بین برنامه‌ها و پرفرمنس همه‌ی آن‌ها بسیار افزایش خواهد یافت در اولین نگاه این تفکر بسیار ناشیانه و بسیار ناممکن بود! تنها روشی که به کار گرفته بودم ارسال اطلاعات از طرف کاربر به سمت سرور و مدیریت آن‌ها تحت معماری Restful Api بود که در قالب JSon آن‌ها را تجزیه و مدیریت می‌کردم. با کمی تحقیق در مورد ویژگی‌های سمت وب  تحت Fast-CGI, uWSGI, DJango, ClearSilver و موارد مرتبط با آن‌ها سعی کردم تا صفحه‌ی بسیار ساده‌ای از HTML را توسط سی‌پلاس‌پلاس هندل کنم. این کار نتایج بسیار موفقیت آمیزی را در بر داشت تا نتیجه‌ی آن تبدیل به یک پروژه‌ی سیستم مدیریت محتوا تحت ++C شد.
      من پروژه‌ای با نام مفهومی Jaguar که نام پروژه‌ی قبلی تحت Php بود را در محیط Qt Creator با C++17 و کتابخانه‌ی Qt باز سازی کرده و هسته‌ی اولیه‌ی آن را برای اجرای چند صفحه از یک وب‌سایت، احراز حویت، بازخوانی و نمایش لیستی از خبر‌ها و مدیریت متا تگ‌ها و آدرس صفحات مربوط به هر صفحه را ایجاد کردم.
      سعی کرده ام در کمترین زمان ممکن برای آزمایش یک سری ویژگی‌های اولیه از یک وب‌سایت آن‌ها را مورد بررسی قرار بدم که عبارتند از هماهنگی با فریم‌ورک‌های طراحی مانند BootStrap و یا Angular.JS که خوشبختانه همه‌چیز بسیار خوب در کنار همدیگه کار می‌کنند. هسته‌ی سیستم به صورت جدا و معماری طراحی آن بر پایه‌ی MVC مورد آزمایش قرار گرفته است.
      در زیر تصاویری از صفحات تولید شده تحت سیستم‌ مدیریت محتوای ساخته شده با سی‌پلاس‌پلاس را مشاهده می‌کنید. 😉







      همه چیز در قدم‌های اول قرار دارد و با توجه به سادگی تولید وب سایت بر خلاف تصوری که داشتیم بسیار توسعه و جای پیشرفت خواهد داشت. بخشی از نمونه کد‌های این سیستم به صورت زیر آورده شده است تا ذهنیتی برای توسعه‌دهندگان ارائه شود:
      تکه کُد زیر عمل ارسال اطلاعات و تمامی لینک‌های مربوط به بوت استرپ را برای سمت HTML ارائه می‌کند که در قالب استاندارد جدید C++17 آورده شده است:
      auto bootstrapCss = bootStrapLib.find("css"); if(bootstrapCss != bootStrapLib.end()) { c->setStash("BootstrapCss", bootstrapCss->second.c_str()); std::cout << "Found " << bootstrapCss->first << " " << bootstrapCss->second << '\n'; } کد مربوط به سمت قالب به صورت زیر خواهد بود:
      <!-- Bootstrap core css --> <link href="{{BootstrapCss}}" rel="stylesheet"> نتیجه‌ی فوق در صورتی که CDN بر روی لوکال تنظیم شده باشد از روی کد‌های کامپایل شده و یا استاتیک فراخوانی خواهد شد. در غیر اینصورت از روی یکی از سرور‌های CDN فراخوانی می‌شوند.
      نحوه‌ی ارسال متغیر از سمت سی‌پلاس‌پلاس به قالب بسیار ساده است! بسیار ساده از Php و یا Node.JS می‌باشد. با در نظر گرفتن ارسال اطلاعات از سمت سی‌پلاس‌پلاس به سمت رابط کاربری کافی است نام متغیر‌ها را در قالب خود اعمال کنید.
      {% for post in news %} <div class="blog-post"> <h2 class="blog-post-title"><a href="news/{{post.uri}}">{{post.title}}</a></h2> <p class="blog-post-meta">{{post.date}} by <a href="#">{{post.author}}</a></p> <p>{{post.announcement|safe}}</p> </div><!-- /.blog-post --> {% endfor %}</div> این ساختار بر پایه‌ی ساختار Angular.JS و DJango پیاده سازی شده است که به طور کامل پشتیبانی می‌شود.
      فعال سازی فناوری Angular.JS بر روی این سیستم جهت طراحی قالب تنها با دو دستور ساده اعمال می‌شود:
      <!-- Link to AngularJS --> <script src= "{{AngularJs}}"></script> <!-- Enable AngularJS Engine --> {{AngularJsSync|safe}} این دستورات در هسته‌ی سیستم مدیریت محتوا در کلاسی با نام Template پردازش و در نهایت به سمت HTML هندل می‌شوند.
      بخشی از دستورات سمت هسته در سی‌پلاس‌پلاس ۱۷ برای مثال ارسال عنوان صفحه به صورت زیر است:
      std::optional<std::string> LoadListTemplate::getTitle() const { if (isset(title)) { return title; } else { return std::nullopt; } } سمت HTML کافی است دستور فوق را در نظر بگیریم:
      <title>{{title}}</title> این‌ها مثال‌هایی از مراحل توسعه‌ی این سیستم است که می‌دانم آنچنان گسترده نیست، اما برای ثابت کردن طراحی و توسعه‌ی وب‌سایت تحت سی‌پلاس‌پلاس مثال‌های روشنی هستند.
       
      موفق و سربلند باشید!
      اطلاعیه‌های مربوط به این پروژه احتمالاً در کانال‌ها و گروه‌ تلگرامی و همین مرجع بازگو و در اختیار شما قرار بگیره.
    • توسط کامبیز اسدزاده
      با سلام،
      همانطور که می‌دانید سیستم‌‌های مدیریت محتوا به عنوان سیستم پویا برای مدیریت محتوای یک وب‌سایت بسیار مفید هستند. حال آنکه یک سیستم مدیریت محتوا فراتر از یک سیستم نرم‌افزاری جهت مدیرین محتوای وب‌سایت توسعه یابد بسیار مفید خواهد بود.
       
      قابلیت‌ها و ویژگی‌ها
      با استفاده از سیستم مدیریت محتوای جگوار (Jaguar) ما می‌توانیم برای مشتریان خود یک سیستم مدیریت چند منظوره با قابلیت‌های کاملاً پویا ارائه دهیم که هر استارتاپی می‌تواند کسب‌و‌کار خود را تحت آن توسعه دهد. این سیستم دارای قابلیت‌های چند سکویی و چند منظوره می‌باشد که یکی از قابلیت‌های برجسته‌ی آن پشتیبانی از سیستم چند زبانه می‌باشد. این سیستم در پلتفرم‌های وب، موبایل و دسکتاپ توسعه داده شده است.
      عنوان: پروژه‌ی جگوار (Jaguar) توضیحات: سیستم مدیریت محتوای چند منظوره و پیشرفته زبان‌ها و فناوری‌های استفاده شده: زبان‌های Php7, JavaScript, CSS3, HTML5 فریم وُرک‌ و کتابخانه‌ها: کتابخانه‌ی JQuery , Angular.JS, BootStrap4 نوع پروژه: تجاری (انحصاری شرکتِ Dotwaves LLC) نویسندگان: کامبیز اسدزاده وضعیت: در حال توسعه حق چاپ و تکثیر: شرکت دات‌ویوز این محصول بر پایه موتور جِنسیس توسعه داده شده است.
      برخی از تصاویر مرتبط با این محصول:








    • توسط veria.kurdish
      سلام خدمت اساتید محترم.
      یک فایل txt دارم با محتویات زیر:
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   d............... 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
          00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................ 
       
      و توسط تکه کد پایین این فایل رو میخونم. دو سوال داشتم خدمت اساتید محترم:
      آیا فانکشن خاصی هست بتونم کاراکتر های نقطه (.) و حرف d را حذف کنم و فقط صفر ها باقی بمونند؟ همین تغییراتی که در فایل انجام دادیم رو بیایم در یک فایل جدید و به صورت باینری ذخیره کنیم؟  
      #include <QCoreApplication> #include <QDataStream> #include <QFile> #include <QString> #include <QDebug> void read(QString filename) { QFile file(filename); if(file.open(QIODevice::ReadWrite)) { qDebug() << "file opened!" << "\n" << "\n"; qDebug() << file.readAll(); } } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QString file = ":/test/1.txt"; read(file); return a.exec(); }
    • توسط کامبیز اسدزاده
      با سلام،
      در این پست من قصد دارم به چند ویژگی استاندارد 1z اشاره کنم که به شما اجازه میده تا کُد تمیزتر، ساده‌تر و خواناتری را ایجاد کنید. توسعه زبان‌های برنامه‌نویسی روز به روز بیشتر شده و سی++ به عنوان یک زبان پیچیده نیاز به این داره تا کاربران رو از لحاظ سادگی و مدرنیزه شدن سینتکس دلگرم کنه.
      در استاندارد جدید ۱۷ من برخی از ویژگی‌ها رو معرفی می‌کنم که در تمیز نوشتن و ساده نوشتن تاثیر بسیاری دارند.
      ویژگی ساختار‌های پیوندی
      این ویژگی یکی از ویژگی‌های جدید سی++ است که امکان پیوند شدن نام‌های مشخص و زیر اشیاء المنت‌های اولیه را می‌دهد. به عبارت ساده‌تر می‌توان گفت که، ساختار‌های پیوندی (Structured Bindings) این توانایی را برای ما می‌دهد تا متغیر‌های چند گانه از یک ساختار (struct) یا tuple را به هم دیگر متصل کنیم.
      *مهمترین هدف Structured Bindings در نسخه‌ی ۱۷ ساده سازی و راحتی درک کد می‌باشد.
      سینتکس این ویژگی به صورت زیر است:
      auto ref-operator(optional)[identifier-list] = expression; // Or auto ref-operator(optional)[identifier-list]{expression}; // Or auto ref-operator(optional)[identifier-list](expression); اجازه دهید تا ما با استفاده ازیک مثال مزایای استفاده از ساختار‌های پیوندی را با کمک tuple ببینیم:
      در نسخه‌ی ۹۸ سی‌پلاس‌پلاس:
      #include <iostream> using namespace std; // Creating a structure named Point struct Point { int x; int y; }; // Driver code int main() { Point p = {1, 2}; int x_coord = p.x; int y_coord = p.y; cout << "X Coordinate : " << x_coord << endl; cout << "Y Coordinate : " << y_coord << endl; return 0; } در نسخه‌ی ۱۱ و ۱۴ سی‌پلاس‌پلاس:
      #include <iostream> #include <tuple> using namespace std; // Creating a structure named Point struct Point { int x, y; // Default Constructor Point() : x(0), y(0) { } // Parameterized Constructor for Init List Point(int x, int y) : x(x), y(y) { } auto operator()() { // returns a tuple to make it work with std::tie return make_tuple(x, y); } }; // Driver code int main() { Point p = {1, 2}; int x_coord, y_coord; tie(x_coord, y_coord) = p(); cout << "X Coordinate : " << x_coord << endl; cout << "Y Coordinate : " << y_coord << endl; return 0; }   در نسخه‌‌ی ۱۷ سی‌پلاس‌پلاس:
      #include <iostream> using namespace std; struct Point { int x; int y; }; // Driver code int main( ) { Point p = { 1,2 }; // Structure binding auto[ x_coord, y_coord ] = p; cout << "X Coordinate : " << x_coord << endl; cout << "Y Coordinate : " << y_coord << endl; return 0; } ویژگی عبارت شرطی و حلقه‌ی جدید
      نسخه‌های جدید از دستورات شرطی switch و if در سی‌پلاس‌پلاس به صورت زیر هستند:
      if (init; condition) و switch (init; condition) قبلاً شما باید به صورت زیر یک دستور شرطی را پیاده سازی می‌کردید:
      { auto val = GetValue(); if (condition(val)) // on success else // on false... } در این قالب مشخص است که val یک محدوده‌ی جداگانه و احتمال نشتی دارد. در نسخه‌ی جدید آن را می‌توان به صورت زیر ساده تر و خواناتر نوشت:
      if (auto val = GetValue(); condition(val)) // on success else // on false... در این نسخه val فقط در داخل حوزه‌ی if و else قابل مشاهده است، بنابراین در این صورت امکان نشتی نخواهد داشت. شرط ممکن است هر نوع شرط باشد و فقط وابسته به val مقدار true/false را بر نمی‌گرداند.
      خُب، چرا این نسخه مفید خواهد بود؟
      فرض کنید قرار است در داخل یک رشته چند چیز را جستجو کنید:
      const std::string myString = "My Hello World Wow"; const auto it = myString.find("Hello"); if (it != std::string::npos) std::cout << it << " Hello\n" const auto it2 = myString.find("World"); if (it2 != std::string::npos) std::cout << it2 << " World\n" ما یا باید نام‌های مختلفی را برای it استفاده کنیم و یا باید آن‌ها را در داخل دامنه‌ی جداگانه قرار دهیم. مانند مثال زیر:
      { const auto it = myString.find("Hello"); if (it != std::string::npos) std::cout << it << " Hello\n" } { const auto it = myString.find("World"); if (it != std::string::npos) std::cout << it << " World\n" } عبارت شرطی جدید if یک دامنه اضافی را فقط در یک خط ایجاد می‌کند:
      if (const auto it = myString.find("Hello"); it != std::string::npos) std::cout << it << " Hello\n"; if (const auto it = myString.find("World"); it != std::string::npos) std::cout << it << " World\n"; همانطور که قبلاً ذکر شد متغیر تعریف شده در عبارت if نیز در بلوک else قابل مشاهده است. بنابراین شما می‌توانید آن را به صورت زیر نیز بنویسید:
      if (const auto it = myString.find("World"); it != std::string::npos) std::cout << it << " World\n"; else std::cout << it << " not found!!\n"; همچنین شما در استاندارد جدید می‌توانید از ويژگی پیوند ساختاری در عبارت شرطی نیز استفاده کنید که قالب آن به صورت زیر است:
      // better together: structured bindings + if initializer if (auto [iter, succeeded] = mymap.insert(value); succeeded) { use(iter); // ok // ... } // iter and succeeded are destroyed here ویژگی Variadic Templates
      در نسخه‌ی ۱۱ ما ویژگی‌ خوبی به نام قالب‌های متنوع یا همان (Variadic Templates) داریم که بسیار عالی است، مخصوصاً وقتی که می‌خواهید با تعداد نامحدود یا متغیر با توابع کار کنید. برای مثال در نسخه‌های قبل از ۱۱ ما مجبور بودیم تا چندین تابع را با ورودی‌های مختلف پیاده سازی کنیم تا بتوانیم به نتیجه‌ی مربوطه برسیم.
      در حال حاضر این ویژگی هنوز هم نیازمند افزودن کد‌های می‌باشد مخصوصاً اگر می‌خواهید تابعی از نوع بازگشتی پیاده سازی کنید. مانند مثال زیر:
      auto SumCpp11(){ return 0; } template<typename T1, typename... T> auto SumCpp11(T1 s, T... ts){ return s + SumCpp11(ts...); } در نسخه‌ی جدید سی++۱۷ ما می‌توانیم این را بسیار ساده تر بنویسیم:
      template<typename ...Args> auto sum(Args ...args) { return (args + ... + 0); } و یا حتی ساده تر...
      template<typename ...Args> auto sum2(Args ...args) { return (args + ...); } این تابع فوق‌العاده است! ورودی‌های متغیر با نوع بازگشتی یکی از پر کاربرد‌ترین توابعی است که در نسخه‌های قبل پیاده سازی آن پیچیده بود.
      ویژگی متغیر‌های درون خطی (Inline variables)
      در قبل از سی++۱۷ ما می‌توانستیم از کلمه‌ی کلیدی inline جهت بهینه‌سازی در زمان کامپال برای توابع استفاده کنیم. حال در نسخه‌ی ۱۷ قابلیت تعریف inline برای متغیر‌ها نیز فراهم شده.
      فرض کنید قرار است متغیری را تعریف کنیم که به صورت ایستا و عمومی مورد استفاده قرار بگیرد. در قبل از نسخه‌ی ۱۷ تعریف آن به این صورت که متغیر در فایل هدر و سورس اعلان و تعریف شوند:
      #ifndef MYCLASS_H #define MYCLASS_H class MyClass { public: MyClass(); static const int myVariable; }; #endif // MYCLASS_H فایل سورس
      #include "myclass.h" MyClass::MyClass() { } const int MyClass::myVariable = 17; و در نهایت تابع و فایل main:
      #include <iostream> #include "myclass.h" int main() { std::cout << "My global variable is : " << MyClass::myVariable << std::endl; return 0; } در استاندارد جدید تعریف تابع در همان زمان اعلان به صورت ایستا و عمومی امکان پذیر شده است. برای مثال:
      #ifndef MYCLASS_H #define MYCLASS_H class MyClass { public: MyClass(); inline static const int myVariable = 17; }; #endif // MYCLASS_H همین تعریف برای اعلان متغیر از نوع ایستا و عمومی کافی است. این کار باعث می‌شود نیازی برای تعریف مقدار متعیر در فایل سورس نباشد.
      مثال‌های دیگر :
      struct MyClass { static const int sValue; }; inline int const MyClass::sValue = 777; و یا ساده تر از آن به شکل زیر:
      struct MyClass { inline static const int sValue = 777; };  
    • توسط سید محمد عباسی
      در این ویدیو آموزش تهیه خروجی برنامه در Qt رو یاد خواهید گرفت.
      لینک دانلود فایل دانلود
×