Learn what Felgo offers to help your business succeed. Start your free evaluation today! Felgo for Your Business

Felgo For Web and JavaScript Developers

This page is for developers who are familiar with web technologies like HTML, CSS and JavaScript. It shows a collection of examples, implemented both in web technologies and Felgo for comparison. Felgo is based on Qt and uses QML as the main language.

QML Introduction for App Development

QML stands for "Qt Markup Language" and is a declarative language designed to describe the user interface of a program: both what it looks like, and how it behaves. In QML, a user interface is specified as a tree of objects with properties. This tree is also often referred to as Scene Graph, because when the parent item moves all children will follow. JavaScript is used as a scripting language in QML. In this section we will cover the basics of QML and its advantages by an example.

As code speaks more than 1000 words, here is a QML example implementing the following:

  • A basic app with a navigation bar holding a title and column with controls.
  • A button that can be clicked to increase a counter.
  • The button also shows the current counter value.
  • A slider that can be dragged.
  • A colored area that changes its height based on the slider value.
  • Looks native on iOS and Android.

How many lines of code would it take you to develop this application with the same functionality in another programming language? With QML, it is just about 30 lines of code:

 import Felgo
 import QtQuick

 App {
   id: app

   property int clickCount: 0 // a property of type integer, to count our button clicks

   NavigationStack { // the NavigationStack displays the navigation bar and lets you push and pop pages

     AppPage {
       title: "QML Introduction" // the title of the active page is displayed in the navigation bar

       Rectangle {
         color: "#e0e2eb"
         width: parent.width // make this rectangle the same width as its parent, which is the page
         height: parent.height * slider.value // this property binding is automatically updated when the slider value changes
       }

       Column {
         anchors.centerIn: parent // center the column in its parent, which is the page

         AppButton {
           id: button
           text: "Click Me! " + app.clickCount // this property binding is automatically updated when the click count changes
           flat: false
           anchors.horizontalCenter: parent.horizontalCenter
           onClicked: {
             app.clickCount++ // increase the click count by 1 on every button click
           }
         }

         AppSlider {
           id: slider
           value: 0.2
         }
       } //Column
     } //Page
   } //NavigationStack
 } //App

Screen Density and Resolution Independent Layout

While the HTML examples will use px values, Felgo offers dp() and sp() functions to get density independent pixel values. This guarantees that the components have the same physical size on any screen. You can also use normal pixel values, but it is best practice to design your apps density and resolution independent. You can find more about this topic here: Create Layouts and Position Components in Your App.

Performing Basic Layout Operations

The following examples show how to perform the most common UI layout tasks.

Styling and Aligning Text

Font style, size, and other text attributes that CSS handles with the font and color properties are individual properties of the AppText component.

In both HTML and Felgo, by default child elements or widgets are anchored at the top left.

 <div class="box">
   Lorem ipsum
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   font: bold 24px Helvetica;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)

   AppText {
     text: "Lorem ipsum"
     font.weight: Font.Bold
     font.pixelSize: sp(24)
     font.family: "Helvetica"
   }
 }

Setting Background Color

Setting a background color with Felgo is as straightforward as with CSS.

 <div class="box">
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)
 }

Centering Components

You can use anchors to center any component in its parent. You can read more about the powerful options of anchoring here: Positioning with Anchoring

To accomplish a similar effect in CSS, the parent element uses either a flex or table-cell display behavior. The examples on this page show the flex behavior.

 <div class="box">
   Lorem ipsum
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   display: flex;
   align-items: center;
   justify-content: center;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)

   AppText {
     text: "Lorem ipsum"
     anchors.centerIn: parent
   }
 }

Manipulating Position and Size

The following examples show how to perform more complex operations on component position, size, and background.

Setting Absolute Position

Components are always positioned relative to their parent. To specify an absolute position for a component, just use its x and y properties.

 <div class="box">
   <div class="inner">
   </div>
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   position: relative;
 }
 .inner {
   background-color: #ef5350;
   width: 100px;
   height: 100px;
   position: absolute;
   top: 24px;
   left: 24px;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)

   Rectangle {
     color: "#ef5350"
     width: dp(100)
     height: dp(100)
     x: dp(24)
     y: dp(24)
   }
 }

Rotating Components

To rotate a comonent, just change its rotation property. You can also apply more complex transformations using the Item::transform property. The default transform origin is the center, you can change it with the Item::transformOrigin property.

 <div class="box">
   <div class="inner">
   </div>
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   display: flex;
   align-items: center;
   justify-content: center;
 }
 .inner {
   background-color: #ef5350;
   width: 100px;
   height: 100px;
   transform: rotate(15deg);
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)

   Rectangle {
     color: "#ef5350"
     width: dp(100)
     height: dp(100)
     rotation: 15
   }
 }

Scaling Components

When you scale a parent component, all its child component are scaled accordingly.

 <div class="box">
   <div class="inner">
   </div>
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   display: flex;
   align-items: center;
   justify-content: center;
 }
 .inner {
   background-color: #ef5350;
   width: 100px;
   height: 100px;
   transform: scale(1.5);
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)

   Rectangle {
     color: "#ef5350"
     width: dp(100)
     height: dp(100)
     scale: 1.5
   }
 }

Applying a Linear Gradient

You can either apply a gradient to a Rectangle directly, or use the LinearGradient component for even more options. This component is available with import Qt5Compat.GraphicalEffects.

Vertical Gradient

The default gradient is drawn as vertical gradient. You can use as many colors as you want, with a position between 0.0 and 1.0.

 <div class="box">
 </div>

 .box {
   width: 320px;
   height: 240px;
   background: linear-gradient(180deg, #ffffff, #000000);
 }
 LinearGradient {
   width: dp(320)
   height: dp(240)
   gradient: Gradient {
       GradientStop { position: 0.0; color: "#ffffff" }
       GradientStop { position: 1.0; color: "#000000" }
   }
 }

Horizontal Gradient

For a horizontal gradient, you need to set the start point to the very left, and the end point to the very right of the component. This way, you can also create gradients at any desired rotation.

 <div class="box">
 </div>

 .box {
   width: 320px;
   height: 240px;
   background: linear-gradient(0deg, #ffffff, #000000);
 }
 LinearGradient {
   width: dp(320)
   height: dp(240)
   start: Qt.point(0,0) // Qt.point(<x>,<y>)
   end: Qt.point(width, 0)
   gradient: Gradient {
       GradientStop { position: 0.0; color: "#ffffff" }
       GradientStop { position: 1.0; color: "#000000" }
   }
 }

Manipulating Shapes

The following examples show how to make and customize shapes.

Rounding Corners

Use the radius property to get rounded corners.

 <div class="box">
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   border-radius: 8px;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)
   radius: dp(8)
 }

Adding Box Shadows

To add a box shadow, you can add a layer effect to your component. The DropShadow type requires an import Qt5Compat.GraphicalEffects.

 <div class="box">
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   box-shadow: 0 5px 5px rgba(0, 0, 0, 0.8);
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)
   layer.enabled: true
   layer.effect: DropShadow {
     radius: 0
     horizontalOffset: dp(5)
     verticalOffset: dp(5)
     color: "#80000000"
   }
 }

Making Circles and Ellipses

Like with CSS, you can create circles by defining a border radius of 50% width to all edges. Additionally you can use the Canvas type to draw shapes using JavaScript.

 <div class="box">
 </div>

 .box {
   background-color: #e0e0e0;
   width: 240px;
   height: 240px;
   border-radius: 50%;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(240)
   height: dp(240)
   radius: width/2
 }

Manipulating Text

The following examples show how to specify fonts and other text attributes. They also show how to transform text strings, customize spacing, and create excerpts.

Adjusting Text Spacing

In CSS you specify the amount of white space between each letter or word by giving a length value for the letter-spacing and word-spacing properties, respectively. The amount of space can be in px, pt, cm, em, etc.

With Felgo you can also set those values in pixels, or the recommended density independent pixels of dp() and sp(). You can find all the available properties in the documentation of AppText and the inherited Text type.

 <div class="box">
   Lorem ipsum
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   display: flex;
   align-items: center;
   justify-content: center;
   letter-spacing: 4px;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)

   AppText {
     text: "Lorem ipsum"
     anchors.centerIn: parent
     font.letterSpacing: sp(4)
   }
 }

Transforming Text

In HTML/CSS, you perform simple case transformations using the text-transform property.

You can apply the same transformations with the font.capitalization property.

 <div class="box">
   Lorem ipsum
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   display: flex;
   align-items: center;
   justify-content: center;
   text-transform: uppercase;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)

   AppText {
     text: "Lorem ipsum"
     anchors.centerIn: parent
     font.capitalization: Font.AllUppercase
   }
 }

Making Inline Formatting Changes

You can use the RichText textFormat to add inline text formatting using HTML markup. You can find the supported HTML markup here: Supported HTML Subset.

 <div class="box">
   Lorem <em>ipsum</em>
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   display: flex;
   align-items: center;
   justify-content: center;
 }
 .box em {
   font-weight: bold;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)

   AppText {
     // you can use < instead of &lt;
     // the &lt; is a little hack to copy this web example
     text: "Lorem &lt;em style=\"font-weight: bold;\">ipsum &lt;/em>"
     anchors.centerIn: parent
     textFormat: Text.RichText
   }
 }

Creating Text Excerpts

An excerpt displays the initial line(s) of text in a paragraph, and handles the overflow text, often using an ellipsis. In HTML/CSS an excerpt can be no longer than one line. Truncating after multiple lines requires some JavaScript code.

With Felgo, you have full control how you want to wrap your text, the maximum number of lines or the maximum maximum height of your excerpt.

 <div class="box">
   Lorem ipsum dolor sit amet, consectetur adipiscing.
 </div>

 .box {
   background-color: #e0e0e0;
   width: 320px;
   height: 240px;
   display: flex;
   align-items: center;
   justify-content: center;
   overflow: hidden;
   text-overflow: ellipsis;
   white-space: nowrap;
 }
 Rectangle {
   color: "#e0e0e0"
   width: dp(320)
   height: dp(240)

   AppText {
     text: "Lorem ipsum dolor sit amet, consectetur adipiscing."
     width: parent.width
     wrapMode: Text.WordWrap
     maximumLineCount: 1
     elide: Text.ElideRight
   }
 }

More examples for common use cases of app development can be found in the Felgo Apps Documentation. The navigation on the left contains the most important components and challenges for developing cross-platform apps.

Run and integrate Felgo Apps within an Existing Website

Felgo Apps run in a browser by using WebAssembly. You can deploy a Felgo app as a standalone app or integrate it into an already existing website. One such example is the Felgo WebEditor that allows you to run a code editor and a live preview side by side.

Felgo also provides a seamless integration between a browser and the QML app. See Sharing data with the Browser to learn more.

Qt_Technology_Partner_RGB_475 Qt_Service_Partner_RGB_475_padded