برنامه‌نویسی گرافیکی آسان با چارچوب Qt-قسمت دهم (پایانی)

برنامه‌نویسی گرافیکی آسان با چارچوب Qt-قسمت دهم (پایانی)

در این جلسه می خواهیم بخش های ناقص ماشین حساب را کامل کنیم ابتدا از Button qml شروع می کنیم

برای اینکه هر کلید بتواند با ماوس هم کار کند از کنترل MouseArea استفاده مي‌کنیم.

  

  property alias text: textItem.text
  

      property color color: "#eceeea"
  

      property bool operator: false
  

      property bool dimmable: false
  

      property bool dimmed: false
    MouseArea {
  

          id: mouse
  

          anchors.fill: parent
  

          anchors.margins: -5
  

          onClicked: {
  

              if (operator)
  

                  window.operatorPressed(parent.text)
  

              else
  

                  window.digitPressed(parent.text)
  

          }
  

      }


توسط خصوصیت operator که از نوع bool است نوع کلید ورودی مشخص می‌شود که عددی است یا عملگر است. پس از تشخیص نوع ورودی تابعی که در فایل اصلی main.qml تعریف کردیم را فراخوانی می‌کنیم. Window شناسه کنترل ریشه فایل مذکور است.
حال برای نوشته روی کلیدها می‌خواهیم انیمیشن استفاده کنیم.

  

  Text {
  

          id: textItem
  

          font.pixelSize: 48
  

          wrapMode: Text.WordWrap
  

          lineHeight: 0.75
  

          color: (dimmable && dimmed) ? Qt.darker(button.color) : button.color
  

          Behavior on color { ColorAnimation { duration: 120; easing.type: Easing.OutElastic} }
  

          states: [
  

              State {
  

                  name: "pressed"
  

                  when: mouse.pressed && !dimmed
  

                  PropertyChanges {
  

                      target: textItem
  

                      color: Qt.lighter(button.color)
  

                  }
  

              }
  

          ]
  

      }


در کنترل text انیمیشن را بر روی رنگ کنترل اجرا می‌کنیم. استفاده از Behavior برای استفاده از قابلیت انیمیشن پیش‌فرض مربوط به تغییر یک خصوصیت است که در اینجا بر روی خصوصیت رنگ کار می‌کند.
حال نیاز به تابعی داریم که وقتی کلید فشرده می‌شود مقدار متغیر dimmed را بروز کند.

  

  function updateDimmed() {
  

          dimmed = window.isButtonDisabled(button.text)
  

      }


برای اینکه با رخداد فشرده شدن کلید این تابع فراخوانی شود باید رخداد ذکر شده را یکبار به تابع بالا متصل کنیم.

  

  Component.onCompleted: {
  

          numPad.buttonPressed.connect(updateDimmed)
  

          updateDimmed()
  

      }


وقتی از Component.onCompleted استفاده می‌کنیم بدنه آن فقط یکبار پس از ساخته شدن کامپوننت که در اینجا کلید است، اجرا می‌شود. برای اتصال دادن رخداد به تابع از connect استفاده می‌کنیم.
نکته قابل توجه این است که در کنترلی مثل MouseArea رخدادی مثل onPressed از قبل تعریف شده و برای استفاده آماده است اما وقتی کامپوننتی را به صورت دستی باید رخدادها را تعریف و فعال کنیم. در اینجا رخداد buttonpressed هنوز آماده استفاده نیست. برای تعریف و فعال‌سازی این رخداد باید به فایل NumberPad.qml رفته و در آن رخداد را فعال کنیم.

  

  signal buttonPressed


کلمه کلیدی signal مشخص می‌کند این کامپوننت رخدادی به اسم buttonPressed دارد که هر جا این کامپوننت اصتفاده شود رخداد ذکر شده نیز قابل استفاده است.
حال باید فایل Display.qml را تکمیل کنیم. توابعی که در صفحه نمایش ماشین حساب کاربرد دارند به صورت زیر هستند.

  

  function displayOperator(operator)
  

      {
  

          listView.model.append({ "operator": operator, "operand": "" })
  

          enteringDigits = true
  

          listView.positionViewAtEnd()
  

      }


این تابع عملگر ورودی را به مدل listview اضافه می‌کند .

  

  function newLine(operator, operand)
  

      {
  

          displayedOperand = displayNumber(operand)
  

          listView.model.append({ "operator": operator, "operand": displayedOperand })
  

          enteringDigits = false
  

          listView.positionViewAtEnd()
  

      }


این تابع  در یک خط عملگر و عدد را به مدل اضافه می‌کند.

  

  function appendDigit(digit)
  

      {
  

          if (!enteringDigits)
  

              listView.model.append({ "operator": "", "operand": "" })
  

          var i = listView.model.count - 1;
  

          listView.model.get(i).operand = listView.model.get(i).operand + digit;
  

          enteringDigits = true
  

          listView.positionViewAtEnd()
  

      }


برای تبدیل ارقام وارد شده به عدد از این تابع استفاده می‌شود.

  

  function setDigit(digit)
  

      {
  

          var i = listView.model.count - 1;
  

          listView.model.get(i).operand = digit;
  

          listView.positionViewAtEnd()
  

      }


تابع بالا برای تغییر یک رقم خاص در صفحه نمایش بکار می‌رود.

  

  function clear()
  

      {
  

          displayedOperand = ""
  

          if (enteringDigits) {
  

              var i = listView.model.count - 1
  

              if (i >= 0)
  

                  listView.model.remove(i)
  

              enteringDigits = false
  

          }
  

      }


این تابع صفحه نمایش ماشین حساب را پاک می‌کند.

  

      function displayNumber(num) {
  

          if (typeof(num) != "number")
  

              return errorString;
  

          
  

          var intNum = parseInt(num);
  

          var intLen = intNum.toString().length;
  

          
  

          // Do not count the minus sign as a digit
  

          var maxLen = num < 0 ? maxDigits + 1 : maxDigits;
  

          
  

          if (num.toString().length <= maxLen) {
  

              if (isFinite(num))
  

                  return num.toString();
  

              return errorString;
  

          }
  

          
  

          // Integer part of the number is too long - try
  

          // an exponential notation
  

          if (intNum == num || intLen > maxLen - 3) {
  

              var expVal = num.toExponential(maxDigits - 6).toString();
  

              if (expVal.length <= maxLen)
  

                  return expVal;
  

          }
  

          
  

          // Try a float presentation with fixed number of digits
  

          var floatStr = parseFloat(num).toFixed(maxDigits - intLen - 1).toString();
  

          if (floatStr.length <= maxLen)
  

              return floatStr;
  

          
  

          return errorString;
  

      }


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

نکته: برای اینکه فایل calculator.js و فایل‌های عکس توسط qml قابل شناسایی باشند توجه داشته باشید که حتماً باید در فایل qml.qrc آدرس دهی شوند. در غیر اینصورت نمی‌توان آن‌ها را import کرد. فایل qml.qrc فایلی با فرمت xml بوده ولی در محیط توسعه qtcreator این فایل را نمی‌توان به صورت دستی ویرایش کرد و موارد گفته شده را به آن افزود. برای ویرایش آن به دایرکتوری پروژه مراجعه نمایید و توسط یک ویرایش‌گر متنی آن را باز کنید. محتویات آن باید به صورت زیر باشد:

 


  

      
  

          main.qml
  

          NumberPad.qml
  

          Button.qml
  

          Display.qml
  

          calculator.js
  

          images/paper-grip.png
  

          images/paper-edge-right.png
  

          images/paper-edge-left.png
  

      
  

  


حال فایل main.cpp را برای اجرای ماشین حساب تغییر می‌دهیم.

#include 
  

  #include 
  

  #include 
  

  int main(int argc, char *argv[])
  

  {
  

      QGuiApplication app(argc, argv);
  

      app.setOrganizationName("Face It");
  

      app.setOrganizationDomain("fitn.ir");
  

      QQuickView view;
  

      view.connect(view.engine(), &QQmlEngine::quit, &app, &QCoreApplication::quit);
  

      new QQmlFileSelector(view.engine(), &view);
  

      view.setSource(QUrl("qrc:///main.qml"));
  

      if (view.status() == QQuickView::Error)
  

          return -1;
  

      view.setResizeMode(QQuickView::SizeRootObjectToView);
  

      view.show();
  

      
  

      return app.exec();
  

  }


برنامه ماشین حساب تکمیل شد. امیدوارم که استفاده کرده باشید. می‌توانید کد کامل ماشین حساب را از آدرس github بنده دریافت نمایید. مجوز آن هم GPLv3 است.


آدرس گیت: https://github.com/saaie/faceit_qml_calculator

 

امین  خزاعی

امین خزاعی

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


0 نظر درباره‌ی این پست نوشته شده است.

ثبت نظر