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

معرفی ابزار کیوبس (Qbs) و پیکربندی آن

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

معرفی ابزار

کیوبس (Qbs) با آوای (“Cubes”) همانند qmake و cmake یک ابزار بسیار ساده و قدرتمند برای ساخت پروژه در پلتفرم‌های مختلف می‌باشد. این ابزار قابلیت استفاده در هر نوع پروژه ای را دارد به‌گونه‌ای که مهم نیست زبان‌برنامه نویسی٬ ابزار‌ها و حتی کتابخانه‌های مورد استفاده چه چیزی باشند. کیوبس یک ابزار همه کاره است که یک نمودار ساخت از پروژه‌های سطح بالا مانند (qmake و cmake) فراهم می‌کند که علاوه بر آن وظیفه اجرای دستورات نمودار ساخته شده در سطح پایین را مانند (make) فراهم می‌کند. در این کتاب ما به پیش معرفی آن می‌پردازیم چرا که قرار است در نسخه ۶ کیوت جایگزین نوع .pro از qmake باشد.

کیوبس برنامه‌ها را بر پایه‌ی اطلاعاتی می‌سازد که در قالب یک فایل QML فراهم می‌شوند. هر فایل پروژه مشخص می‌کند که پروژه می‌تواند شامل چندین محصول باشد و شما نوع پروژه می‌توانیدمشخص کنید که یکی از انواع : نرم افزار، کتابخانه و غیره باشد. مشخصات سیستم مورد نیاز جهت استفاده از ابزار QBS حداقل نسخه ۵.۶.۰ به بعد خواهد بود. این ابزار همراه با Qt ارائه می‌شود.

 

معرفی ساختار QBS در قالب QML

کیوبس برای فایل پروژه خود از پسوند (*.qbs) استفاده می‌کند تا بتواند محتوای موجود در یک پروژه را معرفی کند. به طور کلی یک پروژه شامل چندین محتوا از محصول (پروژه) می‌باشد که در ادامه به آن‌ها اشاره شده است. یک محصول هدفی از روند ساخت است٬ به طور معمول یک برنامه کاربردی٬ کتابخانه و یا شاید یک چیز دیگر می‌تواند هدف آن باشد. جهت بررسی و مدیریت Qbs وارد بخش Setting یا Perefrences شوید و زبانه Qbs را انتخاب کنید تا در این بخش به نسخه و پیکربندی مقادیر مربوط به Qbs دسترسی داشته باشید.

QBS-01.png

مباحثی که در این پست آموزشی پوشش داده خواهد شد:

  • نحوه‌ی استفاده
  • معرفی انواع پروژه‌ها
  • معرفی برخی از پر کاربرد‌ترین آیتم‌های موجود در کیوبس مانند:
    • پروژه Project
    • زیر پروژه SubProject
    • ویژگی‌ها (خواص‌ها) Properties
    • اپلیکیشن Application
    • اپلیکیشن سی‌پلاس‌پلاس CppApplication
    • کتابخانه (پویا) DynamicLibrary
    • کتابخانه (ایستا) StaticLibrary
    • محصول Product
    • پروفایل Profile
    • گروه‌‌بندی Group
    • وابستگی‌ها Depends
    • و ...
  • معرفی ماژول‌های پر کاربرد در کیوبس مانند:
    • ماژول cpp جهت پیکربندی و پشتیبانی از C++ و ویژگی‌های آن در کیوبس
    • پیکربندی ماژول‌های کیوت
    • پیکربندی ویژگی‌های پردازنده
    • پیکربندی اختصاصی اندروید
    • پیکربندی اختصاصی محصولات اپل
    • پیکربندی Xcode
    • پیکربندی ماژول‌های کیوت
    • پیکربندی Java
    • و ...
  • در صورت نیاز به مباحث دیگری نیز اشاره خواهد شد.

نحوه‌ی استفاده

جهت استفاده از کیوبس کافی است با سینتکس JavaScript یا QML آشنا باشید. جهت پیکربندی یک پروژه سی‌پلاس‌پلاس نمونه کُد آن به صورت زیر خواهد بود:

import qbs 1.0

Application {
    name: "helloworld"
    files: "main.cpp"
    Depends { name: "cpp" }
}

انواع پروژه‌ها در کیوبس به چهار دسته‌ی زیر تقسیم بندی می‌شوند:

  1. تولید اپلیکیشن ساده (Application)
    • این نوع پروژه به عنوان یک آیتم از محصول می‌باشد. 
       
      Application {
          Depends { name: "cpp" }
      }
  2. تولید اپلیکیشن تحت وابستکی و ویژگی‌های سی‌پلاس‌پلاس (CppApplication)
    • به عنوان یک محصول که تحت وابستگی‌های ماژول Cpp می‌باشد استفاده می‌شود.
       
      CppApplication {
      
       cpp.cxxLanguageVersion: "c++11"
              
       files: [
          "main.cpp",
          "qml.qrc",
         ]
      }
  3. تولید پروژه در قالب کتابخانه‌ی پویا (DynamicLibrary)
    • این نوع زمانی مورد استفاده قرار می‌گیرد که قرار است پروژه را در قالب یک خروجی کتابخانه‌ی پویا تولید کنیم.
       
      Product {
          type: "dynamiclibrary"
      }
  4. تولید پروژه در قالب کتابخانه‌ی استاتیک (StaticLibrary)
    • این نوع زمانی مورد استفاده قرار می‌گیرد که قرار است پروژه را در قالب یک خروجی کتابخانه‌ی ایستا تولید کنیم.
    • مثال
       
      Product {
          type: "staticlibrary"
      }

       

در یک پروژه برای مشخص کردن فایل‌های قابل استفاده، نام و وابستگی‌ها به سادگی می‌توانند مشخص شوند. برای مثال در صورتی که پروژه‌ی شما تحت فناوری کیوت و Qt Quick است کافی است مقدار Depends را مشخص کنید:

Depends { name: "Qt.core" }
Depends { name: "Qt.quick" }

لیستی از آیتم‌های (پر کاربرد و پایه) در QBS

  • آیتم پروژه (Project) به عنوان یک آیتم از پروژه مجموعه‌ای از محصولات و خواص‌های مربوط به آن‌ها را ارائه می‌دهد.
  • آیتم زیر پروژه‌ (Sub Project) یک ایتم زیر پروژه برای اضافه کردن یک پروژه به عنوان زیر مجموعه پروژه می‌باشد که در یک فایل جداگانه تعریف شده است.
        SubProject {
            filePath: "Subproject/OtherProject.qbs"
            Properties {
                name: "A sub-project"
            }
        }
  • آیتم خواص (Properties) شرایط دستوری و خاصیت‌های مورد نیاز را برای یک محصول ایجاد می‌کند.
     Product {
          Properties {
              condition: qbs.targetOS.contains("windows")
              ...
              .....
          }
      }
    - خواص condition از نوع بولین جهت شرط سازی سایر موارد در یک محصول را فراهم می‌کند.
    - خواص overrideListProperties لیست خواص تنظیم شده را که در ماژول‌ها به دست می آید را بر می‌گرداند.
     
  • آیتم اپلیکیشن Application به عنوان یک آیتم با نوع 'application' برای یک محصول تعریف می‌شود.
  • آیتم اپلیکیشن سی‌پلاس‌پلاس CppApplication به عنوان یک محصول با وابستگی‌های لازم در سی‌پلاس‌پلاس می‌باشد.
  • آیتم کتابخانه‌‌ی پویا (DynamicLibrary) به عنوان یک آیتم برای محصول از نوع کتابخانه در قالب داینامیک (پویا) می‌باشد.
    import qbs
    
    Project {
        minimumQbsVersion: "1.7.1"
        
        CppApplication {
    
            type: "dynamiclibrary"
            ...
            
            Group {    
                // Properties for the produced executable
                fileTagsFilter: "application"
                qbs.install: true
            }
        }
    
    }

     

  • آیتم کتابخانه‌‌ی ایستا (StaticLibrary) به عنوان یک آیتم برای محصول از نوع کتابخانه در قالب استاتیک (ایستا) می‌باشد.
    import qbs
    
    Project {
        minimumQbsVersion: "1.7.1"
        
        CppApplication {
    
            type: "staticlibrary"
            ...
            
            Group {    
                // Properties for the produced executable
                fileTagsFilter: "application"
                qbs.install: true
            }
        }
    
    }

     

  • آیتم محصول (Product) به عنوان یک محصول (Product) به طور معمول نتیجه یک فرآیند ساخت را ارائه می‌دهد. مجموعه ای از فایلهای ورودی و خروجی را مشخص می‌کند. برای مثال نمونه‌ی زیر محصول را به عنوان یک پروژه سی پلای پلاس تنظیم می‌کند.
    Product {
          name: "helloworld"
          type: "application"
          files: "main.cpp"
          Depends { name: "cpp" }
      }

    خواص عضو در محصول (Product)

 

  • aggregate : bool
  • buildDirectory : path
  • builtByDefault : bool
  • condition : bool
  • consoleApplication : bool
  • destinationDirectory : string
  • excludeFiles : stringList
  • files : stringList
  • multiplexByQbsProperties : stringList
  • multiplexedType : stringList
  • name : string
  • qbsSearchPaths : stringList
  • sourceDirectory : path
  • targetName : string
  • type : stringList
  • version : string 

 

  • عضو aggregate اگر مقدارش برابر با true باشد، محصولی را که تحت وابستگی چندگانه باد در قالب یک محصول جمع آوری شده تولید خواهد کرد. در صورتی که شما نمی‌خواهید چنین کاری کنید بهتر است آن را به صورت تعریف نشده در نظر بگیرید.
  • عضو buildDirectory دایرکتوری (ریشه مسیر) برای ساخت محصول است. فایل‌های تولید شده بعد از کامپایل در این مسیر قرار خواهند گرفت که به صورت پیش فرض توسط Qbs مقدار دهی می‌شود و کاربر نمی‌تواند آن را تغییر دهد.
  • عضو buildByDefault تعیین کننده ساخت محصول است. اگر مقدارش false باشد، عمل ساخت محصول تنها در زمان درخواست صریح صورت خواهد گرفت که دستور ساخت آن توسط پارامتر --products و یا استفاده از --all-products برای دستور ساخت استفاده خواهد شد. مقدار آن به صورت پیشفرض true می‌باشد.
  • عضو condition تعیین می‌کند که محصول ساخته خواهد شد، اگر مقدارش false باشد، محصول ساخته نخواهد شد. مقدار این عضو به صورت پیشفرض true است.
  • در ویندوز، تعیین می‌کند که برنامه تحت GUI تولید شود یا تحت کنسول. اگر مقدار آن برابر true باشد،  یک اپلیکیشن تحت کنسول تولید خواهد شد. در غیر این صورت یک اپلیکیشن تحت رابط کاربری (GUI) تولید خواهد شد. در پلتفرم‌های اپل، به نوع برنامه به صورت پیشفرض بستگی دارد. اگر مقدارش true باشد، یک برنامه اجرایی طبیعی تولید خواهد شد در غیر این صورت، بسته‌ی نرم‌ا‌فزاری تولید می‌شود.
  • عضو destinationDirectory مسیری است که در هدف مصنوعات قرار می‌گیرد. اگر یک مسیر نسبی داده شود آن را به عنوان دایرکتوری پایه برای project.buildDirectory تنظیم می‌کند.
  • عضو exclude-files لیست فایلهای منبع یا سورس را شاملش نمی‌شود. برای موارد معروف و خاص مفید است.
  • عضو files لیستی از فایل های منبع یا سورس را شامل می‌شود. 
  • عضو multiplexByQbsProperties مشخص می‌کند که کدام خواص ماژول qbs برای استفاده از محصولات چندگانه استفاده شود.
  • عضو multiplexedType نوع محصول را برای نمونه محصولات چند گانه مشخص می‌کند. در صورتی که نیاز به این خواص ندارید می‌توانید آن را تعریف نکنید.
  • عضو name نام محصول را اعمال میکند. مقدار آن باید بر اساس یک عبارت جاوا اسکریپتی باشد.
    
      CppApplication {
          name: "hello" + "world"
          // valid
      }
      CppApplication {
          name: "app_" + qbs.targetOS.join("_")
          // invalid
      }
    
  • عضو qbsSearchPath با مقدار project.qbsSearchPaths ادغام خواهد شد که لیستی از مسیرها را برای وارد کردن ماژول‌ها جستجو می‌کند.
  • عضو sourceDirectory دایرکتوری یا مسیر منبع را برای محصول مشخص می‌کند. این دایرکتوری برای فایل‌هایی که در محصول تعریف شده اند می‌باشد.
  • عضو targetName نام پایه فایل است که با هدف مصنوعات برای محصول می‌باشد. مقدار نام فایلی که نامعتبر باشد توسط کاراکتر زیر خط جایگزین می‌شود.
  • عضو type برچسب‌های فایل مربط به مصنوعات محصول را مشخص می‌کند.
  • عضو version شماره نسخه محصول را مشخص می‌کند. برای کتابخانه‌های به اشتراک گذاری شده و همچنین فایل Info.plist تحت محصولات اپل مورد استفاده می‌گیرد.
     
  • آیتم پروفایل (Profile) به عنوان پروفایل سفارشی می‌تواند برای تعریف اهداف و شرایط ساخت بر روی یک ماشین خاص تنظیم شود.
        Profile {
                  name: "my-special-profile"
                  qbs.toolchainType: "gcc"
                  qbs.targetPlatform: "linux"
                  qbs.architecture: "armv7a"
                  cpp.toolchainInstallPath: "/opt/special-gcc/bin"
                  cpp.toolchainPrefix: "arm-linux-gnueabi-"
              }
    
              qbs.profiles: ["my-special-profile"]
    

     

  • آیتم گروه (Group) جهت تعریف گروه‌های مختلف در فایل‌هایی که شامل یک محصول می‌باشند مورد استفاده قرار می‌گیرد. این ویژگی در محیط توسعه برای مدیریت پروژه‌های بزرگ بسیار کارآمد و مفید است.
     Application {
          Group {
              name: "common files"
              files: ["myclass.h", "myclass_common_impl.cpp"]
          }
          Group {
              name: "Windows files"
              condition: qbs.targetOS.contains("windows")
              files: "myclass_win_impl.cpp"
          }
          Group {
              name: "Unix files"
              condition: qbs.targetOS.contains("unix")
              files: "unixhelper.cpp"
              Group {
                  name: "Linux files"
                  condition: qbs.targetOS.contains("linux")
                  files: "myclass_linux_impl.cpp"
              }
              Group {
                  name: "FreeBSD files"
                  condition: qbs.targetOS.contains("freebsd")
                  files: "myclass_freebsd_impl.cpp"
              }
              Group {
                  name: "macOS files"
                  condition: qbs.targetOS.contains("macos")
                  files: "myclass_macos_impl.cpp"
              }
              Group {
                  name: "PS4 Pro files"
                  condition: qbs.targetOS.contains("linux")
                  files: "myclass_macos_impl.cpp"
              }
              Group {
                  name: "Xbox One X files"
                  condition: qbs.targetOS.contains("windows")
                  files: "myclass_macos_impl.cpp"
              }
          }
          Group {
              name: "Files to install"
              qbs.install: true
              qbs.installDir: "share"
              files: "runtime_resource.txt"
          }
      }
    
  • آیتم وابستگی (Depends) یک آیتم وابستگی در یک محصول یا ماژول تعریف می‌شود. به عنوان مثال محصول زیر ماژول Qt Quick، Qt Core و Qt Gui را بارگیری می‌کند.
        Product {
            
            Depends { name: "Qt.core" }
            Depends { name: "Qt.quick" }
            Depends { name: "Qt.gui" }
        }

    و یا به روش زیر تحت کتابخانه‌ی Qt ماژول‌های مربوطه را بارگیری می‌کند.
     

        Product {
            Depends { name: "Qt"; submodules: ["core", "quick", "gui"] }        
        }

    ترکیبی از ماژول‌های مختلف از پروژه‌های مختلف به صورت زیر خواهد بود:
     

        Product {
            Depends { name: "cpp" }        
            Depends { name: "MyEngine"; submodules: ["module1", "module2", "module3"] }                
            Depends { name: "Qt"; submodules: ["core", "quick", "gui"] }        
        }

     

معرفی ماژول‌های پر کاربرد در Qbs

  • ماژول cpp جهت پیکربندی و پشتیبانی از C++ و ویژگی‌های آن در کیوبس
    • برخی از ویژگی‌های موجود در این ماژول به صورت زیر آورده شده‌اند:

 

  • allowUnresolvedSymbols : bool
  • alwaysUseLipo : bool
  • architecture : string
  • archiverName : string
  • archiverPath : string
  • assemblerFlags : stringList
  • assemblerName : string
  • assemblerPath : string
  • automaticReferenceCounting : bool
  • cFlags : stringList
  • cLanguageVersion : stringList
  • combineCSources : bool
  • combineCxxSources : bool
  • combineObjcSources : bool
  • combineObjcxxSources : bool
  • commonCompilerFlags : stringList
  • compilerDefinesByLanguage : var
  • compilerFrameworkPaths : pathList
  • compilerIncludePaths : pathList
  • compilerLibraryPaths : pathList
  • compilerName : string
  • compilerPath : string
  • compilerPathByLanguage : var
  • compilerVersionMajor : int
  • compilerVersionMinor : int
  • compilerVersionPatch : int
  • compilerWrapper : stringList
  • cppFlags : stringList
  • cxxFlags : stringList
  • cxxLanguageVersion : stringList
  • cxxStandardLibrary : string
  • debugInformation : bool
  • defines : stringList
  • discardUnusedData : bool
  • distributionFrameworkPaths : pathList
  • distributionIncludePaths : pathList
  • distributionLibraryPaths : pathList
  • driverFlags : stringList
  • driverLinkerFlags : stringList
  • dsymutilFlags : stringList
  • dsymutilPath : string
  • dynamicLibraries : stringList
  • enableCompilerDefinesByLanguage : stringList
  • enableExceptions : bool
  • enableReproducibleBuilds : bool
  • enableRtti : bool
  • endianness : string
  • entryPoint : string
  • exceptionHandlingModel : string
  • exportedSymbolsCheckMode : string
  • frameworkPaths : pathList
  • frameworks : stringList
  • generateManifestFile : bool
  • includePaths : pathList
  • libraryPaths : pathList
  • linkerFlags : stringList
  • linkerMode : string
  • linkerName : string
  • linkerPath : string
  • linkerWrapper : stringList
  • lipoPath : string
  • minimumIosVersion : string
  • minimumMacosVersion : string
  • minimumTvosVersion : string
  • minimumWatchosVersion : string
  • minimumWindowsVersion : string
  • nmName : string
  • nmPath : string
  • objcFlags : stringList
  • objcopyName : string
  • objcopyPath : string
  • objcxxFlags : stringList
  • optimization : string
  • platformDefines : stringList
  • positionIndependentCode : bool
  • prefixHeaders : pathList
  • requireAppContainer : bool
  • requireAppExtensionSafeApi : bool
  • rpathOrigin : string
  • rpaths : stringList
  • runtimeLibrary : string
  • separateDebugInformation : bool
  • soVersion : string
  • sonamePrefix : string
  • staticLibraries : stringList
  • stripName : string
  • stripPath : string
  • systemFrameworkPaths : pathList
  • systemIncludePaths : pathList
  • systemRunPaths : stringList
  • treatSystemHeadersAsDependencies : bool
  • treatWarningsAsErrors : bool
  • useCPrecompiledHeader : bool
  • useCxxPrecompiledHeader : bool
  • useLanguageVersionFallback : bool
  • useObjcPrecompiledHeader : bool
  • useObjcxxPrecompiledHeader : bool
  • useRPathLink : bool
  • useRPaths : bool
  • variantSuffix : string
  • visibility : string
  • warningLevel : string
  • weakFrameworks : stringList
  • windowsApiAdditionalPartitions : stringList
  • windowsApiCharacterSet : string
  • windowsApiFamily : string 
  • با توجه به لیست بالا، به برخی از ویژگی‌های موجود در این لیست اشاره می‌کنیم.
  • ویژگی cxxLanguageVersion و cLanguageVersion جهت تعیین کردن پشتیبانی از نسخه‌ی زبان‌های سی‌پلاس‌پلاس و سی مورد استفاده قرار می‌گیرد که مشخصه‌های آن به ترتیب برای سی‌پلاس‌پلاس c++98 | c++11 | c++14 | c++17 و برای سی c89 | c98 | c11 می‌باشند. 
    cpp.cLanguageVersion: "c11"
    cpp.cxxLanguageVersion: "c++17"

     

نقل قول

این آموزش ادامه دارد...

  •  
  • پسندیدن 1

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


لینک به ارسال
به اشتراک گذاری در سایت های دیگر
مهمان
این موضوع برای عدم ارسال قفل گردیده است.

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

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

  • مطالب مشابه

    • توسط کامبیز اسدزاده
      با سلام،
      در این پُست ما قصد داریم در رابطه با نحوه‌ی آغاز یادگیری کیوت توضیح دهیم. اینکه به عنوان یک تازه‌کار چه پیش‌نیازاتی را باید مطالعه و در نهایت چگونه و تحتِ چه منابعی این کتابخانه‌ی قدرتمند را بیاموزیم. همچنین پاسخ برخی از سوالات شما را در این پُست به طور شفاف ارائه شده است که طیِ چندین سال سوال علاقه مندان بوده‌اند 🙂.
       
      پیش‌نیازات برای یادگیری کتابخانه‌ی Qt
      دانش متوسط و به بالا در رابطه با زبان‌ برنامه‌نویسی مُدرن سی‌پلاس‌پلاس نسخه‌‌های ۱۱ به بعد، (بنابراین اگر شما هیچ اطلاعی در رابطه با ساختار برنامه‌های سی‌پلاس‌پلاس و نحوه‌ی عملکرد آن ندارید، شانس موفقیت شما بسیار پایین خواهد بود و ممکن است برنامه‌ی تولید شده‌ی شما به بدترین شکل ممکن پیاده سازی شود). ما پیشنهاد می‌کنیم قبل از آن با زبان سی‌پلاس‌پلاس آشنا شوید. آشنایی با کامپایلر و نحوه‌ی عملکرد آن در پلتفرم‌های مختلف از جمله ویندوز، مک‌او‌اِس، لینوکس، اندروید و آی‌او‌اِس آشنایی با برنامه‌نویسی در معماری‌های مختلف مانند x86، x64، Arm و غیره... آشنایی با معماریِ سیستم‌عامل‌ها، برای مثال اگر قرار است از خاصیت چند-سکویی کیوت استفاده کنید تا یک برنامه‌ی تحت اندروید را توسعه دهید، در این صورت باید در نظر داشته باشید که شما بدون درکِ معماری سیستم‌عامل اندروید و پیکربندی برنامه در مراحل توسعه نمی‌توانید به راحتی از پسِ این کار بر آیید. آشنایی با اصطلاحات و مفاهیم تجربه‌ی کاربری و رابط کاربری جهت طراحی مناسب با فناوری‌های Qt Widget و Qt Quick (در صورتی که علاقه‌مند به طراحی ظاهر برنامه‌های خلاقانه دارید) آشنایی Xml و JavaScript برای طراحی رابط گرافیکی تحت فناوری‌های فوق  
      آیا کیوت یک زبان برنامه‌نویسی است، چرا نحوِ (Syntax) آن با سی‌پلاس‌پلاس استاندارد فرق می‌کند؟
      خیر، کیوت ابتدا به عنوان یک کتابخانه‌ی رابط گرافیکی کاربر توسعه داده شده است که بعد‌ها برای توسعه اهدافِ بیشتری شامل کتابخانه‌های شبکه و غیره شده است که در قالب یک چهارچوب (فریم‌وُرک) که تحت زبان برنامه‌نویسی سی‌پلاس‌پلاس برای این زبان توسعه یافته است و در زمینه‌های مختلفی کاربرد‌های فراوان دارد. دلیل زیبایی و ظاهر ساده‌ی آن ساختار بسیار قدرتمند آن است که موجب شده همانند چهارچوب‌های قدرتمند دیگری خودنمایی کند. (اما قول این ظاهر و سادگی آن را نخورید، چون با سی‌پلاس‌پلاس طرف هستیم 😨)
      آیا کیوت از سرویس‌ها و قابلیت‌های اختصاصی‌ِ اپلیکیشن‌های اندروید و آی‌او‌اِس را به طور کامل پشتیبانی می‌کند؟
      خیر، هیچ ابزاری به صورت چند-سکویی فعلاً (تاکید می‌کنیم - فعلاً تا به این تاریخ) وجود ندارد که تمامی امکانات اختصاصی این پلتفرم‌ها را پشتیبانی کند. اما این به این معنی نیست که جواب منفی خواهد بود، لذا شما در برنامه‌نویسی سی‌پلاس‌پلاس به راحتی می‌توانید برای پلتفرم‌های فوق با سرویس‌های آن‌ها ارتباط برقرار کنید اما! این کار کمی نیاز به دانش فنی بالایی خواهد داشت. برای مثال (دسترسی به سرویس‌های اندروید یا آی‌او‌اس) با ترکیب کُد‌های آبجکتیو-سی و جاوا امکانپذیر است. این کار به راحتی قابل انجام خواهد بود و کافی است شما در رابطه با نحوه‌ی ترکیب کُد‌های این زبان‌ها مطلع باشید.
      کیفیت خروجی برنامه‌های تحت کیوت چگونه است؟
      اگر شما واقعاً یک برنامه‌نویسِ ماهرِ سی‌پلاس‌پلاس باشید می‌توانید برنامه‌ای را تولید کنید که بسیار خوش دست‌تر و سریعتر از برنامه‌های پیشفرضِ پلتفرم‌ها باشد. اگر غیر از این باشد برنامه‌ی شما بسیار بد و کُند عمل خواهد کرد و بهتر است سراغ زبان‌های بومیِ (هر پلتفرم) بروید. هرچند سی‌پلاس‌پلاس یک زبان بومی برای تمامی پلتفرم‌ها محسوب می‌شود اما این ریسک برای افراد مبتدی پیشنهاد نمی‌شود. معمولاً برنامه‌های گسترده و عظیم توسط سی‌پلاس‌پلاس توسعه داده می‌شوند که برنامه‌نویسان آن واقعا حرفه‌ای و با قوانین این زبان آشنا هستند.
      آیا برای تولید برنامه‌های مک و آی‌او‌اس نیاز به سیستم خاصی داریم؟
      بله، شما بدون وجود سیستم‌عامل مک نمی‌توانید برنامه‌ای را بر روی دستگاه‌های اپِل کامپایل کنید. این امر مستلزمِ سیستم عامل اختصاصی این شرکت بوده و باید توسعه دهنده دارای حساب کاربری معتبر سالانه باشد تا بتواند برنامه‌ی خود را بر روی دستگاه‌های مورد نظر اجرا کند. در غیر این صورت تنها می‌تواند برنامه‌ی خود را بر روی سیستم خود مورد آزمایش و خطا قرار دهد.
      آیا کیوت در ایران بازار کار مناسبی دارد، آیا ارزش دارد من این کتابخانه را یاد بگیرم؟
      خوشبختانه کیوت بیشتر از ۲۰ سال است که در دنیا مورد استفاده قرار می‌گیرد و کشور‌های پیشرفته از آن استقبال می‌کنند. در کشور ما مدتی است این کتابخانه مورد استقبال قرار گرفته و بسیاری از شرکت‌ها مایل به ساخت و توسعه‌ی برنامه‌های خود تحت این کتابخانه هستند که برخی از دلایل آن (بهره بردن از قابلیت‌های زبان سی و سی‌پلاس‌پلاس و ویژگی‌های خاص آن است).
      آیا کیوت از پلتفرم وِب پشتیبانی می‌کند؟
      کیوت از تمامی پلتفرم‌ها پشتیبانی می‌کند، مخصوصاً با پشتیبانی از ماژول‌های QtWebEngine و QtWebAssembly این امر امکانپذیر است که برنامه‌های خود را تحت فناوری‌های وِب نیز توسعه دهید.
      آیا من حتماً باید به زبان سی‌پلاس‌پلاس مسلط باشم؟
      ما بر این تاکید نمی‌کنیم که شما حتماً باید سی‌پلاس‌پلاس را کامل یاد بگیرید، این زبان به قدری گسترده است که نمی‌توان درباره‌ی آن به این راحتی مدعی شد. اما قوانین و اصول اولیه و عامیانه‌ی زبان بسیار نیاز است. کتاب‌ها و مقالات مربوط به این زبان را بیاموزید و تا جایی که می‌توانید خود را ارتقاء دهید.
      من دانشجو یا متخصص رشته‌ی کامپیوتر نیستم، آیا می‌توانم این کتابخانه را یاد گرفته و از آن در توسعه برنامه‌های مورد نظر خود استفاده کنم؟
      بله، اما ممکن است در تجزیه و تحلیل رفتار‌های سیستم‌عامل، مدیریت خطاها و پیکربندی ابزار‌های تخصصی (برنامه‌نویسی) با مشکلاتی مواجه شوید که تنها متخصصات این رشته می‌توانند آن را درک و حل کنند. آیا واقعاً حجم برنامه‌های کیوت نسبت به Net. یا Java بیشتر است !؟
      خیر، به طور ذاتی برنامه‌های توسعه داده شده توسط سی‌++ دارای کمترین حجم برنامه هستند، معمولاً کتابخانه‌های استاندارد این زبان به صورت پیشفرض بر روی سیستم عامل‌ها تعبیه شده و در دسترس قرار دارند. اما شما در ویندوز زمانی که با دات‌نت برنامه‌نویسی می‌کنید، فریمورک مربوطه از قبل بر روی سیستم عامل ویندوز نصب بوده و بدون آن هیچ برنامه‌ی نوشته شده توسط دات‌نِت قابل اجرا نمی‌باشد. اما چون از قبل این کتابخانه بر روی سیستم‌عامل تعبیه شده است شما نیاز به تنها داشتن فایل اجرایی دارید و نیازی نیست فریم‌ورک دات‌نت را در کنار فایل اجرایی خود مستقر کنید. بنابراین حجم مربوط به چهارچوب به چشم نیامده و اینطور به نظر می‌رسد که برنامه‌های تحت دات نت بسیار سبُک‌تر هستند! متاسفانه این تفکری اشتباه است 😌 برنامه‌های تحت سی‌پلاس‌پلاس نسبت به زبان‌های دیگر کم حجم‌تر و سبُک‌تر بوده و شما کافی است فایل‌های مربوط به کتابخانه را در کنار برنامه‌ی خود داشته باشید. در رابطه با کتابخانه‌ی Qt نیز باید گفت کیوت به عنوان یک چهارچوب مانند دات نت شامل کلاس‌ها و ماژول‌هایی است که باید همانند دات نت بر روی سیستم عامل تعبیه شود اما چون اینکار به صورت جداگانه در کنار برنامه‌ی شما قرار می‌گیرد اینگونه تصور می‌شود که برنامه‌های مبتنی بر کیوت نسبت به دات نت از حجم بیشتری برخوردار هستند. این کاملاً طبیعی بوده و به عنوان نکته ضعف نیست.
      من علاقه‌ی خاصی به سی‌پلاس‌پلاس دارم و می‌خواهم کیوت را یاد بگیرم، از کجا و چه تحت منابعی باید شروع کنم؟
      خوشبختانه کیوت از لحاظ مستندات بسیار جامع است و شما می‌توانید از آدرس https://doc.qt.io به تمامی مستندات مورد نیاز خود دسترسی داشته باشید. همچنین اگر نگران اینترنت خود هستید و یا به آن دسترسی مداوم ندارید می‌توانید از داخل محیط توسعه‌ی کیوت کریتور از بخش Help آن مستندات مورد نیاز خود را به صورت آفلاین دریافت کنید.
      من دنبال کتاب آموزشی کیوت هستم، آیا کیوت کتاب‌های آموزشی مفیدی در این زمینه از مقدمه تا پیشرفته دارد؟
      بله، در این بخش شما می‌توانید کتاب‌هایی را در این زمینه مشاهده کنید که مرجع رسمی‌ِ کیوت آن‌ها را تایید کرده است.
      من به زبان انگلیسی تسلط کافی ندارم، ترجیح می‌دهم که از مراجع فارسی معتبر استفاده کنم، آیا کیوت در این زمینه منابعی دارد که معتبر باشند؟
      خوشبختانه کیوت به قدری طعمِ جذابی برای برنامه‌نویسان دارد که ما اقدام به تالیف و پیاده سازی آموزش‌هایی در این زمینه کرده‌ایم، شما می‌توانید دو کتاب مقدماتی و پیشرفته‌ی این کتابخانه را تهیه کنید که در کتاب‌خانه‌ی ملی کشور به صورت رسمی به ثبت رسیده اند و عبارتند از نسخه‌‌های مقدماتی برای Qt Widgets و نسخه‌ی پیشرفته برای Qt Quick (این کتاب‌ها تجاری هستند).
      آیا مقالات یا کتاب‌های آموزشی رایگانی هم برای کیوت وجود دارد؟
      خوشبختانه به لُطف برخی از دوستان برخی از مطالب در قالب PDF جمع آوری شده است. فایل آن را از این بخش می‌توانید دریافت کنید. همچنین کتاب‌های تجاری در برخی از روز‌های ویژه شامل تخفیف قرار می‌گیرند که مُختص کاربران رسمی مرجع می‌باشد.
      آیا لیستی برای مشاهده‌ی برنامه‌های توسعه یافته توسط Qt داریم؟
      بسیاری از برنامه‌های قدرتمند و خارق‌العاده‌ای توسط سی‌پلاس‌پلاس توسعه داده می‌شوند که می‌توان لیست عظیمی از آن‌ها را نام برد. اما در این میان لیستی از برنامه‌هایی که تحت کیوت توسعه داده شده‌اند در این بخش آمده است.
      برای یادگیری استاندارد سی‌پلاس‌پلاس و تقویت مهارت خود در این زبان کدام مقالات و کتاب‌ها را پیشنهاد می‌کنید؟
      علاوه بر این که شما می‌توانید در مرجع به دنبال آموزش‌های مرتبط با این زبان باشید، پیشنهاد ما این است که از مراجع رسمی آن نیز استفاده کنید. برخی از آن‌ها به صورت زیر آمده‌اند:
      cppreference.com http://www.cplusplus.com/ Learn C++ C++ Tutorial | SoloLearn: Learn to code for FREE! Learn C++ (Introduction and Tutorials to C++ Programming) اگر سوالی داشته باشم کجا می‌توانم آن را مطرح کرده و به پاسخ خود برسم؟
      شما می‌توانید برای سوال و پرسش در انجمن‌های این مرجع اقدام کنید. اساتید و دوستان با تجربه سوالات شما را دریافت و مناسبترین پاسخ‌ها را ارائه خواهند داد. همچنین شما می‌توانید ما را در گروه‌ و کانال تلگرامی دنبال کنید.
      نکته (در این پُست بنابر اهداف فرهنگ‌سازی برای حق چاپ) فایل‌های مرتبط با کتاب‌های آموزشی زبان اصل و یا زبان فارسی قرار داده نشده است. کتاب‌های زیادی در رابطه با این زبان وجود دارند که به زبان اصلی می‌باشند اما برای احترام به نویسنده‌ی آن‌ها از ارسال چنین فایل‌هایی معذوریم🙂.
      این پُست ممکن است ویرایش یا به‌روز رسانی شود.
    • توسط کامبیز اسدزاده
      همانطور که می‌دانید در سال ۹۵ نسخه اول ومقدماتی اولین کتاب برنامه نویسی سی پلاس پلاس همراه با کتابخانه کیوت انتشار یافت، طبق بازخورد‌هایی که از علاقه مندان و خوانندگان کتاب چه در نسخه رایگان و چه در نسخه تجاری به این نتیجه رسیدیم که محتوایی فراتر از محتوای مقدماتی که تحت برنامه نویسی سنتی بود در اختیار شما قرار دهیم.

      * تمامی حقوق مادی و معنوی این کتاب متعلق به مولف و ناشر مولف (کامبیز اسدزاده) می‌باشد و هرگونه کپی برداری از آن پیگرد قانونی خواهد داشت.
      توجه : در داشتن هر گونه انتقاد و پیشنهاد در رابطه با این کتاب با آدرس شخصی نویسنده (kambiz.ceo@gmail.com) مکاتبه نمایید. نکته : این کتاب در روز‌های خاص ممکن است شامل تخفیف قرار بگیرد. نکته دوم : کسانی که این کتاب را یک بار خریداری می‌کنند نسخه‌ی به روز رسانی شده آن را به صورت رایگان می‌توانند دریافت کنند. برخی از درخواست‌ها در کتاب مقدماتی به صورت زیر بودند:
      آموزش پیشرفته در رابطه با QML و آشنایی با آن آموزش برقراری ارتباط بین ++C و QML به صورت بک اند و فرانت اند آموزش کار با کنترل‌ها و نحوه سفارشی سازی پروژه آموزش برقراری ارتباط با پایگاه داده و فناوری های مرتبط با آن آموزش نحوه پیکربندی کیت‌ها٬ کامپایلر و ... آموزش نحوه توسعه برنامه بر روی پلتفرم های مختلف از حمله اندروید٬ آی او اس و ... و درخواست‌های دیگر... بنابراین بر اساس این درخواست‌ها و محتوایی که نیاز می باشد بعد از جلد مقدماتی با آن‌ها آشنا باشید را در این نسخه فراهم کرده ایم.
      نکته از نظر من در رابطه با محتوا:
       کتابخانه کیوت شامل مباحث بسیار زیادی است که می‌توان از هزاران صفحه محتوای آموزشی تولید کرد. اما در این محتوای آموزشی من تنها به مواردی اشاره کرده ام که لازمه کار هستند و در پروژه‌ها می‌بایست اطلاعات لازم در رابطه با آن‌ها داشته باشید.
      هزینه این کتاب چطور و بر چه اساسی خواهد بود؟
      همانطور که می‌دانید هزینه مقدماتی کتاب در ویرایش اول و دوم با قیمت ۱۰.۰۰۰ تومان و در ویرایش سوم با قیمت ۲۰.۰۰۰ هزار تومان در اختیار علاقه مندان قرار گرفته است که شامل بهبود و توسعه قالب و محتوای آن بر اساس بازخورد ها بوده است.
      قیمت این جلد در حال حاضر۶۵.۰۰۰ تومان در نظر گرفته شده است که در قالب A4 با تعداد حداقل فعلی۳۰۰ صفحه توسعه یافته است و در مرحله اول در قالب PDF منتشر خواهد شد.
      نسخه چاپی این کتاب چطور خواهد بود؟ آیا برنامه ای برای آن خواهید داشت؟ 
      بر اساس بازخورد‌هایی که داشته ایم بیش از ۸۵ درصد علاقه مندان مایل به دریافت نسخه الکترونیکی کتاب بودند که در آن می‌توانند به راحتی کد‌های نوشته شده را در محیط توسعه خود کپی کنند بنابراین نسخه الکترونیکی در اولویت اول قرار گرفته است که می‌توان در کمترین زمان ممکن آن را آماده کرد.
      اما در رابطه با نسخه چاپی باید طبق مراحل مورد نیاز زمانی را صرف عقد قرارداد و توافق با ناشر در نظر بگیریم که ممکن است چند ماه بعد از نسخه الکترونیکی به تصویب رسیده و منتشر شود. (فعلا تصمیم قطعی در رابطه با این موضوع گرفته نشده است) این بستگی به استقبال علاقه مندان خواهد داشت و هزینه آن با نسخه الکترونیکی مجزا خواهد بود.
      سرفصل ها و محتوا چه چیز‌هایی هستند؟
      محتوای کتاب طبق آخرین استاندارد کتابخانه بر پایه نسخه ۵.۸ به بالا می‌باشد. محتوای آن به نسخه ۵.۹ و حتی ۵.۱۰ به صورت پیش نویسه به روز رسانی شده است. همچنین ویژگی های و موارد مهمی که در نسخه ۵.۹ و ۵.۱۰ موجود هستند در این کتاب به آن‌ها اشاره شده است.
      سر فصل‌های نهایی و تایید شده کتاب: 
      فصل اول مقدمه بر زبان ++C برخی از قابلیت‌ها ساختار برنامه در ++C کتابخانه‌ها فرق بین C و ++C ویژگی‌های معرفی شده در ++C ویرایش‌های ۱۱ ٬ ۱۴ و ۱۷ کامپایلر‌های ++C و وضعیت آن‌ها ساختار اسناد ++C در پروژه‌ کاربرد این زبان در کجاست؟ استاندارد‌های زبان مقدمه کیوت (Qt) معرفی کیوت (Qt) ۵.۹ آشنایی با محیط توسعه، نصب و راه اندازی همراه با پیکربندی کیت (Kit) در آن نصب و راه اندازی محیط Qt پیکربندی کیت‌ها در macOS پیکربندی کیت‌ها در Linux پیکربندی کیت‌ها در Windows معرفی محیط توسعه کیوت کرِیتور (Qt Creator) نسخه 4 پیکربندی و تنظیمات مربوط به ساخت برای پلتفرم‌های مختلف معرفی مجوز های Qt و نحوه استفاده از مناسبترین مجوز لوگو‌های نشانگر ساخته شده با Qt پشتیبانی از انواع پلتفرم‌ها پشتیبانی از انواع معماری ها شرایط و قوانین لازم جهت انتشار اپلیکیشن در فروشگاه iTunes یا همان (Apple Store) شرایط و قوانین لازم جهت انتشار اپلیکیشن در فروشگاهWindows Store شرایط و قوانین لازم جهت انتشار اپلیکیشن در فروشگاه Google Play شرایط و قوانین اختصاصی برنامه تحت Qt جهت انتشار و پذیرش در فروشگاه های مرتبط فصل دوم معرفی فناوری Qt Quick ویرایش 2 معرفی زبان کیو اِم اِل (QML) ویرایش 2 آشنایی با سبک - سینتَکس (Syntax) زبان QML روش اعلام یا اظهار یک شیء در QML اشیاء فرزند (Child-Object) در QML سبک و روش اعمال اظهار نظر (Comment) در QML صفت های اشیاء در QML پشتیبانی از جاوا اسکریپت (JavaScript) و ترکیب آن با QML روش استفاده از جاوا اسکریپت در سند QML روش های ترکیب ++C و استفاده از آن در سند QML فصل سوم معرفی انواع پروژه ها تحت فناوری کیوت کوئیک (Qt Quick) معرفی پروژه از نوع Qt Widget Application معرفی پروژه از نوع Qt Console Application معرفی پروژه از نوع Qt Quick Application معرفی پروژه از نوع Qt Quick Controls 2 Application معرفی پروژه از نوع Qt Quick Controls Application معرفی پروژه از نوع Qt Quick Canvas 3D Application معرفی پروژه از نوع Qt Quick Labs Controls Application آغاز ایجاد پروژه تحت C++ و Qt Quick ساده ترین برنامه معرفی کلاس QGuiApplication معرفی کلاس QQmlApplicationEngine معرفی کلاس QCoreApplication معرفی تابع exect در پروژه فصل چهارم انواع کنترل ها، منو ها و دیگر آبجکت ها معرفی انواع QML پایه در فناوری Qt Quick نوع date نوع color نوع font نوع matrix4x4 نوع point نوع quaternion نوع rect نوع size نوع vector2d نوع vector3d نوع vector4d معرفی انواع اشیاء QML در فناوری Qt Quick معرفی Accessible معرفی AnchorAnimation معرفی AnchorChanges معرفی AnchorImage معرفی AnimatedSprite معرفی Animation معرفی AnimationController معرفی Animator معرفی Behavior معرفی BorderImage معرفی Contex2D معرفی Canvas معرفی CanvasGradient معرفی CanvasImageData معرفی CanvasPixelArray معرفی CanvasColorAnimation معرفی Column معرفی DoubleValidator معرفی Drag معرفی DragEvent معرفی DropArea معرفی EnterKey معرفی Flickable معرفی Flipable معرفی Flow معرفی FocusScope معرفی FontLoader معرفی FontMeteric معرفی Gradient معرفی GridMesh معرفی GridView معرفی Image معرفی IntValidator معرفی Item معرفی ItemGraResult معرفی KeyEvent معرفی KeyNavigation معرفی Keys معرفی LayoutMirror معرفی ListView معرفی Loader معرفی MouseArea معرفی MouseEvent معرفی MultiPointTouchArea معرفی NumberAnimation معرفی OpacityAnimator معرفی ParallelAnimation معرفی GraphicInfo معرفی ParentAnimation معرفی ParentChange معرفی Path معرفی PathAnimation معرفی PathView معرفی PauseAnimation معرفی PropertyAction معرفی PropertyChanges معرفی Rectangle معرفی RegExpValidator معرفی Repeater معرفی Rotation معرفی RotationAnimation معرفی RotationAnimator معرفی Row معرفی Scale معرفی ScaleAnimator معرفی SecuentialAnimation معرفی ShaderEffect معرفی ShaderEffectSource معرفی Shortcut معرفی SmoothedAnimation معرفی SpringAnimation فصل پنجم معرفی انواع کنترل های 2 Qt Quick Controls کنترل AbstractButton کنترل ApplicationWindow کنترل BusyIndicator کنترل Button کنترل ButtonGroup کنترل CheckBox کنترل CheckDelegate کنترل ComboBox کنترل Container کنترل Control کنترل Dial کنترل Drawer کنترل Frame کنترل GroupBox کنترل ItemDelegate کنترل Label کنترل Menu کنترل MenuItem کنترل Page کنترل PageIndicator کنترل Pane کنترل Popup کنترل ProgressBar کنترل RadioButton کنترل RadioDelegate کنترل RangeSlider کنترل ScrollBar کنترل ScrollIndigator کنترل Slider کنترل SprinBox کنترل StackView کنترل SwipeDelegate کنترل SwipeView کنترل Switch کنترل SwitchDelegate کنترل TabBar کنترل TabButton کنترل TextArea کنترل TextField کنترل ToolBar کنترل ToolButton کنترل ToolTip کنترل Thumbler فصل ششم معرفی Qt Quick Dialog (دیالوگ های انتخاب رنگ، فایل، فونت و پیغام) معرفی Color Dialog معرفی Font Dialog معرفی File Dialog معرفی Message Dialog معرفی Qt Quick Layouts معرفی Column Layout معرفی Grid Layout معرفی Row Layout معرفی Stack Layout معرفی Qt Quick Control Styles (سبک و استایل نویسی کنترل ها – سفارشی سازی) واکنش گرایی و پاسخ دهی محتوای وب در اپلیکیشن با Qt WebEngine محتوای چند رسانه ای در کیوت QMultimedia محتوای چند رسانه ای در کیوت QMultimedia پخش صوت ظبط صدا در فایل پخش ویدیو کار با دوربین فصل هفتم معرفی و پیکربندی کار با بانک اطلاعاتی (دیتابیس) کار با بانک اطلاعاتی و ارتباط آن بین C++ و QML معرفی و کار با XML معرفی و کار با JSON معرفی و کار با QSetting سفارشی سازی فایل .pro  پروژه فصل هشتم مقایسه انواع حالت های کامپایل Debug و Release نحوه افزودن دیگر کتابخانه های C++‎‎ در محیط Qt Creator و استفاده همراه با کتابخانه Qt فرق بین کامپایل استاتیک و داینامیک نحوه خروجی گرفتن / گسترش (Deployment) در Qt پیکربندی و انتشار برنامه در پلتفرم ویندوز (Windows) پیکربندی و انتشار برنامه در پلتفرم مک (macOS) پیکربندی و انتشار برنامه در پلتفرم لینوکس (Linux) پیکربندی و انتشار برنامه در پلتفرم‌های iPhone و iPad (iOS) پیکربندی و انتشار برنامه در پلتفرم اندروید (Android) معرفی ابزار کیوبس (QBS) به روز رسانی کیوت بدون دریافت فایل نصبی آفلاین اهداف نسخه‌های ۵.۱۰ و ۶
    • توسط xarion
      سلام.
      من یه منو دارم که به صورت زیر ساخته می شه
      QQuickView *leftMenuView = new QQuickView(); leftMenuView->rootContext()->setContextProperty("autoTr", QString()); leftMenuView->rootContext()->setContextProperty("ctrlOptions", ctrlOptions); leftMenuView->rootContext()->setContextProperty("ctrlLeftMenu", ctrlLeftMenu); leftMenuView->setSource(QUrl("qrc:/LeftMenu.qml")); leftMenuWidget = QWidget::createWindowContainer(leftMenuView, this); leftMenuWidget->setMinimumWidth(280); leftMenuWidget->setVisible(false); QVBoxLayout* leftMenuLayout = new QVBoxLayout(); leftMenuLayout->addWidget(leftMenuWidget); scanAreaLayoutOverlap->addLayout(leftMenuLayout, 0, 0, Qt::AlignLeft); برای باز و بسته شدن هم دو تا فانکشن Open و Close دارم که visibility رو خاموش و روشن می کنه.
      حالا مشکل اینه که من می خوام توی eventFilter بتونم event هایی که مربوط به فوکوس leftMenuWidget هست رو پاسخ بدم. ولی مشکل اینه که هیچ event دریافت نمی کنم ولی وقتی که leftMenuView رو به eventfilter وصل می کنم event ها رو دریافت می کنم. کسی می تونه کمکم کنه که بتونم از containter رویداد مربوطه اش رو بگیرم
×