torstai 2. tammikuuta 2014

Sailfish ja PyOtherSide - esimerkki



Kun teemme Sailfish ohjelmia niin käytämme Qt Creatoria ja QML ohjelmointikieltä, koska QML ei ihan kaikkeen sentään taivu, niin apuna on yleensä C++ ,  mutta hyvä on myös tietää että Pythonia on myös mahdollisuus käyttää C++ tilalla.

Qt Creatorin mukana ei kuitenkaan tule Python editoria, vaan meidän on asennettava siihen PyQt.
On myös olemassa vaihtoehto tälle eli PyOtherSide, jota ei kuitenkaan kiinnitetä mitenkään Qt Creator:in toisin kuin PyQt , vaan pelkästään ladataan emulaattoriin, sekä tämän lisäksi myös Python 3.3  (toki myös näin on tehtävä itse laitteeseen)

PyOtherSiden käyttö siis tarkoittaa ettei Qt Creatorista tule varsinaista Python editoria, mutta koska Qt Creator kuitenkin sallii myös muitten kun .qml tiedostojen liittämisen projektiin (ja tämä on suuri apu) voimme koodata Python tiedostoa samalla kun koodaamme QML tiedostoa, kunhan koodaaja vaan itse hallitsee Pythonin sisennykset.
Pythonia kutsutaan silloin QML komponentista nimeltä Python.

Mer wikin mukaan Sailfish Harbour tulee tukemaan PyOtherSide:a.

Kokeillaan  miten tämä toimii, tehdään pieni ohjelma jossa käytämme Pythonia apuna. Esimerkissä soitamme jolla-ringtone.wav tiedoston, ja ProgressBar (Sailfish.Silica komponentti) liukuu soiton edetessä ... tähän käytämme Pythonia, haemme sillä kappaleen keston.
---------
Aluksi:
(katso ylempänä olevaa Mer linkkiä, itse asensin kuitenkin zypperin emulaattoriin:  pkcon install zypper)

kirjaudu emulaattoriin: ssh -p 2223 nemo@localhost

asenna emulaattoriin:

zypper ar http://repo.merproject.org/obs/mer-python3/latest_i486/mer-python3.repo
zypper in python3-base
zypper in pyotherside-qml-plugin-python3-qt5

Varmista että python3 toimii
Siirrä jokin soitettava .wav tiedosto ~/Music/ hakemistoon

(/usr/share/sounds/jolla-ringtones/stereo/jolla-ringtone.wav)
--------

Editorissa:
Luodaan uusi projekti -- SailfishOS Qt Quick application
Projektin SecondPage.qml kopio alla oleva  koodi

import QtQuick 2.0
import Sailfish.Silica 1.0
import QtMultimedia 5.0
import io.thp.pyotherside 1.0

Page {

    property string sound_name: "jolla-ringtone.wav"
    property string sound_path: "/home/nemo/Music/"
//-------
    Text {
        id:input
        text: "<b>"+sound_name+"</b><br><i> .. press me ..</i>"
        color: "yellow"
        font.pointSize: 24
        anchors.centerIn: parent
        MouseArea {
            anchors.fill: parent
            onPressed:{
                       playMusic.play()
                       bar.value = 0; bar._timer.running = true
                       input.color = "steelblue"
                       input.text = "<i>"+sound_name+"</i>"}
                 }
    }
//------------
   Python {
           id:py
           Component.onCompleted: {

               addImportPath(Qt.resolvedUrl('.').substr('file://'.length));

               importModule('duration', function() {
                   call('duration.read_header',[sound_path+sound_name],function(result){
                      playMusic.source = "file:///"+sound_path+sound_name
                      bar._timer.interval = result;

                   });
               });
           }
           onError: console.log('Python error: ' + traceback)
       }

//---------------
        SoundEffect {id: playMusic }

//-----------------
             ProgressBar {
                 id : bar
                 anchors.fill: parent
                 minimumValue: 0
                 maximumValue: 100
                 valueText: value + "%"
                  _timer.repeat: true
                  _timer.running: false
                  _timer.onTriggered: {
                     bar.value ++;
                     if (bar.value == 100) { _timer.running = false;
                         if (playMusic.playing == false) { bar.value = 0 }
                 }
                          }

             }
//------------------
}

Kohta: property string sound_name: "jolla-ringtone.wav"
Korjaa tähän sen tiedoston nimi mitä käytät
-----
Itse Python tiedosto lisätään editorin vasemmassa ylälaidassa olevassa hakemistopuun kohtaan 

Other files -- qml/pages

Hiiren oikealla --- add new
Python -- Python source file
Anna tiedostolle nimi -- duration.py
Polun loppuosa pitää olla   ~/qml/pages
Lataa alla oleva koodi

duration.py
---------
import os
import struct
import pyotherside

def read_header(wav_file):

    try:
        handled_file = open(wav_file, 'rb')
    except IOError:   #, err:
        return ("tiedostoa %s" % (wav_file)+" .. ei ole")

    buffer = handled_file.read(38)
    # varmista tiedosto
    if (buffer[0:4] != b"RIFF") or (buffer[12:16] != b"fmt "):
         return ("ei standardi WAV tiedosto")

    by_rate = struct.unpack('<L', buffer[28:32])[0] # Bytes/Second


    # lue datalohkot

    Alfa = 0
    handled_file.seek(0, 2) # tiedoston lopusta
    FileSize = handled_file.tell()

    Position = 12 # jump > WAVE

    while 1:
        # alilohko
        handled_file.seek(Position)
        buffer = handled_file.read(8)
        if buffer[0:4] == b"data":
           Alfa = Position
            break
        Position += (8 + struct.unpack('<L', buffer[4:8])[0])
        if Position >= FileSize:
            break


#--- shown pituus sek.
    if Alfa != 0:
        handled_file.seek(Alfa)
        buffer = handled_file.read(8)
        size = int("%s" % struct.unpack('<L', buffer[4:8]))
        size = int((size / by_rate)*10) # x 10
        handled_file.close()

        return size      #size
    else:
        return 0

pyotherside.atexit(read_header)

-----------------------

Tallenna ja aja ctrl-r

Python lukee .wav tiedoston headerin, ja sieltä etsii soitettavan datan koon, joka sitten jaetaan byte per sekunti arvolla x 10, tulos on pyöristetty kokonaisluku ja annetaan ProgressBar:lle 
bar._timer.interval = result

Kun Python funktiota kutsutaan, se tapahtuu QML koodissa.

call ('duration.read_header',[sound_path+sound_name],function(result)

duration.read_header =  duration tiedostosta read_header funktio

parametrit funktiolle annetaan [] lista merkkien sisällä

Ei kommentteja:

Lähetä kommentti