FiveTech Support Forums

FiveWin / Harbour / xBase community
Board index FiveTouch Maybe Important - 2015-07-31 16:05 UTC-0800 Pritpal Bedi (be
Posts: 154
Joined: Thu Jun 03, 2010 06:27 AM
Maybe Important - 2015-07-31 16:05 UTC-0800 Pritpal Bedi (be
Posted: Sat Aug 01, 2015 01:47 AM

2015-07-31 16:05 UTC-0800 Pritpal Bedi (bedipritpal at hotmail.com)(r417)
+ hbqtqmlparts

  • hbqtqmlparts/resources
  • hbqtqmlparts/resources/png
  • hbqtqmlparts/resources/png/left-32.png
  • hbqtqmlparts/resources/png/refresh-32.png
  • hbqtqmlparts/resources/png/right-32.png
  • hbqtqmlparts/resources/png/stop-32.png
  • hbqtqmlparts/resources/qml
  • hbqtqmlparts/resources/qml/BarcodeReader.qml
  • hbqtqmlparts/resources/qml/WebView.qml
  • hbqtqmlparts/resources/wav
  • hbqtqmlparts/resources/wav/barcode-beep.wav
  • hbqtqmlparts/resources/wav/camera-flash.wav

  • hbqtqmlparts/misc.prg

  • hbqtqmlparts/qmlbridge.prg
  • hbqtqmlparts/barcodereader.prg
  • hbqtqmlparts/webview.prg

  • hbqtqmlparts/hbqtqmlparts.hbc

  • hbqtqmlparts/hbqtqmlparts.hbp
  • hbqtqmlparts/hbqtqmlparts.hbx
  • hbqtqmlparts/hbqtqmlparts.qrc

  • hbqtqmlparts/tests

  • hbqtqmlparts/tests/demobarcodereader.prg
  • hbqtqmlparts/tests/demowebview.prg
  • hbqtqmlparts/tests/hbmk.hbm

  • qtcontribs.hbp

    • Added: hbqtqmlparts/hbqtqmlparts.hbp

    Initial commit of Harbour engine for QML manipulation.

    QML is the next-generation offering by Qt which facilitates to develop
    modern-looking, javaScript based applications. QML is also the core
    language adopted by Ubuntu mobile plaforms and its concept of
    one-os-fit-all-devices shift. So seems QML is set to become the
    protocol of choice for so many applications.

    Harbour's implementation of Qt, i.e. HbQt, is essentially a widget
    based implementation. It took me a while to turn to QML because
    of the necessity to have barcode reading inside my mobile offerings.
    I remained reluctant to give QML a try for a long time because of the
    complexity how Signal/Slot mechanism is implemented in Harbour.
    But when I took initiative, I found that it is simpler than my fear.
    Bottom line is : we can start using QML to some extent alsong-with
    and within our existing widget based apps.

    CLASS HbQtQmlBridge() provides the building blocks to stream-line
    the complexity of signal/slots, set/get properties, execute methods, etc.

    CLASS HbQtQmlBridge()

    METHOD init( oParent )
    METHOD create( oParent )

    METHOD setQml( cQml ) -> lSuccess
    METHOD show() -> NIL
    METHOD setProperty( cProperty, xValue ) -> lSuccess
    METHOD setChildProperty( cChild, cProperty, xValue ) -> lSuccess
    METHOD getProperty( cProperty ) -> oQVariant | NIL
    METHOD getChildProperty( cChild, cProperty ) -> oQVariant | NIL
    METHOD invokeMethod( cMethod, ... ) -> oQVariant | NIL
    METHOD connect( cSignal, bBlock ) -> lSuccess
    METHOD connectChild( cChild, cSignal, bBlock ) -> lSuccess

    :create() only initiates a QQuickWidget(), set some of its
    properties, connects it to error handeling slots and
    lays it in a best-judged layout on its parent.

    :setQml( cQml ) is where all the action happens.
    This is the only place where we could know if a QML
    document has been loaded or not. All subsequest operations
    are executable only if we succeed here. Be noted that QML
    engine is a scripting engine and is based on JavaScript
    heavily.

    Lets disect CLASS HbQtBarcodeReader() and BarcodeReader.qml in
    relevant context only. HbQtBarcodeReader() is developed to provide
    one-line calling methodology in mind and has many other constructs
    you are already familiar with.

    METHOD HbQtBarcodeReader:create( oParent )
    ...
    ...
    // register C++ classes in order to access them inside QML
    // immediately before those are about to be Used
    //
    HBQAbstractVideoSurface():registerQmlTypes()
    QZXing():registerQmlTypes()

    ::oQmlBridge := HbQtQmlBridge():new():create( ::oQmlContainerWidget )

    // provide the QML document location needed
    //
    IF ::oQmlBridge:setQml( "qrc:/hbqtqml/resources/qml/BarcodeReader.qml" )
    ::stopCamera()

     #ifndef __ANDROID__
        // because QVideoProbe() is only available for Android
        // we need render the frame ourselves, so this connection
        //
        ::oQmlBridge:connectChild( "videosurface", "imageAvailable(QImage)", {| oImage | ::dispImage( oImage ) } )
     #endif
     // we could have connected the "qzxing" child also for the same effect
     // but we decided to receive signal via QML document as it implements 
     // more constructs.
     //
     ::oQmlBridge:connect( "tagFound(QString)", {| cTag | ::manageBarcodeFound( cTag ) } )
    
     __hbqtAppRefresh()
    

    ENDIF
    ...
    ...
    RETURN self

    BarcodeReader.qml [ only relevant parts ]:

    Rectangle {
    id : cameraUI
    objectName : "camerainterface" // name to access the object
    // as this is the root object
    // it can be accessed directly.

    property bool stopScanningFrames   // can be set/get via :setProperty
    
    signal imageCaptured( string image )
    signal tagFound( string tag )      // signal we will receive via :connect
    
    function startScanning() {
       stopScanningFrames = false;
    }
    function stopScanning() {
       stopScanningFrames = true;
    }
    function stopCamera() {            // method we will invoke via :invokeMethod
        cameraUI.stopScanning();
        camera.stop();
    }
    function startCamera() {
        camera.start();
        cameraUI.startScanning();
        myVideoSurface.decoder = decoder;
        myVideoSurface.source  = camera;
    }
    
    Camera {
        id: camera
        objectName: "camera"           // can be accessed as QObject
                                       // from PRG QObject can only be 
                                       // exploited via :connect()
    }
    
    VideoOutput {
        id               : viewfinder
        objectName       : "viewfinder"
        source           : Qt.platform.os == "android" ? camera : myVideoSurface
    }
    
    QZXing{
        id         : decoder
        objectName : "qzxing"
        onTagFound : {
            if( ! cameraUI.stopScanningFrames )
            {
                cameraUI.stopScanningFrames = true;
                playSoundCameraFlash.play();
                cameraUI.tagFound( tag ); // emit the signal which we :connect()ed
            }
        }
    }
    
    HBQAbstractVideoSurface{
        id         : myVideoSurface
        objectName : "videosurface"   // will connect via :connectChild()
    }
    
    SoundEffect {
        id      : playSoundCameraFlash
        source  : "qrc:/hbqtqml/resources/wav/barcode-beep.wav"
    }
    

    }

    A convinient function, one-liner, can be fired to scan a barcode as:
    __hbqtActivateBarcodeReader( {|cBarcode| LetMePushIntoField( cBarcode ) } )

    I hope this class will flourish with passage of time as we will gain
    more experience into QML and allied technology. I am impressed with
    results and plan to share with you whatever meaningful I could muster.

    Enjoy and stay tuned!

Pritpal Bedi
a student of software analysis & concepts

enjoy hbIDEing...
Pritpal Bedi
http://hbide.vouch.info/
Posts: 44158
Joined: Thu Oct 06, 2005 05:47 PM
Re: Maybe Important - 2015-07-31 16:05 UTC-0800 Pritpal Bedi (be
Posted: Sat Aug 01, 2015 08:06 AM

Pritpal,

Many thanks for telling us

Great job! :-)

regards, saludos

Antonio Linares
www.fivetechsoft.com

Continue the discussion