├── pythonsample.png ├── pythonsample.desktop ├── rpm ├── pythonsample.changes.in ├── pythonsample.yaml └── pythonsample.spec ├── pythonsample.pro └── qml ├── cover ├── coveractions.py └── CoverPage.qml ├── pythonsample.qml └── pages ├── datadownloader.py └── FirstPage.qml /pythonsample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sailfishos/python-sample/HEAD/pythonsample.png -------------------------------------------------------------------------------- /pythonsample.desktop: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | X-Nemo-Application-Type=silica-qt5 4 | Icon=pythonsample 5 | Exec=sailfish-qml pythonsample 6 | Name=pythonsample 7 | 8 | -------------------------------------------------------------------------------- /rpm/pythonsample.changes.in: -------------------------------------------------------------------------------- 1 | # Rename this file as pythonsample.changes to include changelog 2 | # entries in your RPM file. 3 | # 4 | # Add new changelog entries following the format below. 5 | # Add newest entries to the top of the list. 6 | # Separate entries from eachother with a blank line. 7 | 8 | # * date Author's Name version-release 9 | # - Summary of changes 10 | 11 | * Sun Apr 13 2014 Jack Tar 0.0.1-1 12 | - Scrubbed the deck 13 | - Hoisted the sails 14 | 15 | 16 | -------------------------------------------------------------------------------- /pythonsample.pro: -------------------------------------------------------------------------------- 1 | # NOTICE: 2 | # 3 | # Application name defined in TARGET has a corresponding QML filename. 4 | # If name defined in TARGET is changed, the following needs to be done 5 | # to match new name: 6 | # - corresponding QML filename must be changed 7 | # - desktop icon filename must be changed 8 | # - desktop filename must be changed 9 | # - icon definition filename in desktop file must be changed 10 | # - translation filenames have to be changed 11 | 12 | # The name of your application 13 | TARGET = pythonsample 14 | 15 | CONFIG += sailfishapp_qml 16 | 17 | SOURCES += 18 | 19 | OTHER_FILES += qml/pythonsample.qml \ 20 | qml/cover/CoverPage.qml \ 21 | qml/pages/FirstPage.qml \ 22 | rpm/pythonsample.changes.in \ 23 | rpm/pythonsample.spec \ 24 | rpm/pythonsample.yaml \ 25 | pythonsample.desktop \ 26 | qml/cover/coveractions.py \ 27 | qml/pages/datadownloader.py 28 | -------------------------------------------------------------------------------- /rpm/pythonsample.yaml: -------------------------------------------------------------------------------- 1 | Name: pythonsample 2 | Summary: Python SailfishOS sample 3 | Version: 1.0 4 | Release: 1 5 | # The contents of the Group field should be one of the groups listed here: 6 | # http://gitorious.org/meego-developer-tools/spectacle/blobs/master/data/GROUPS 7 | Group: Qt/Qt 8 | URL: https://github.com/sailfishos 9 | License: LICENSE 10 | # This must be generated before uploading a package to a remote build service. 11 | # Usually this line does not need to be modified. 12 | Sources: 13 | - '%{name}-%{version}.tar.bz2' 14 | Description: | 15 | A Sailfish OS sample application written in Python. 16 | Configure: none 17 | # The qtc5 builder inserts macros to allow QtCreator to have fine 18 | # control over qmake/make execution 19 | Builder: qtc5 20 | 21 | # This section specifies build dependencies that are resolved using pkgconfig. 22 | # This is the preferred way of specifying build dependencies for your package. 23 | PkgConfigBR: 24 | - sailfishapp >= 1.0.2 25 | - Qt5Core 26 | - Qt5Qml 27 | - Qt5Quick 28 | 29 | # Build dependencies without a pkgconfig setup can be listed here 30 | # PkgBR: 31 | # - package-needed-to-build 32 | 33 | # Runtime dependencies which are not automatically detected 34 | Requires: 35 | - sailfishsilica-qt5 >= 0.10.9 36 | - pyotherside-qml-plugin-python3-qt5 37 | - libsailfishapp-launcher 38 | 39 | # All installed files 40 | Files: 41 | # - '%{_bindir}' 42 | - '%{_datadir}/%{name}' 43 | - '%{_datadir}/applications/%{name}.desktop' 44 | - '%{_datadir}/icons/hicolor/86x86/apps/%{name}.png' 45 | 46 | # For more information about yaml and what's supported in Sailfish OS 47 | # build system, please see https://wiki.merproject.org/wiki/Spectacle 48 | 49 | -------------------------------------------------------------------------------- /rpm/pythonsample.spec: -------------------------------------------------------------------------------- 1 | # 2 | # Do NOT Edit the Auto-generated Part! 3 | # Generated by: spectacle version 0.27 4 | # 5 | 6 | Name: pythonsample 7 | 8 | # >> macros 9 | # << macros 10 | 11 | %{!?qtc_qmake:%define qtc_qmake %qmake} 12 | %{!?qtc_qmake5:%define qtc_qmake5 %qmake5} 13 | %{!?qtc_make:%define qtc_make make} 14 | %{?qtc_builddir:%define _builddir %qtc_builddir} 15 | Summary: Python SailfishOS sample 16 | Version: 1.0 17 | Release: 1 18 | Group: Qt/Qt 19 | License: LICENSE 20 | URL: https://github.com/sailfishos 21 | Source0: %{name}-%{version}.tar.bz2 22 | Source100: pythonsample.yaml 23 | Requires: sailfishsilica-qt5 >= 0.10.9 24 | Requires: pyotherside-qml-plugin-python3-qt5 25 | Requires: libsailfishapp-launcher 26 | BuildRequires: pkgconfig(sailfishapp) >= 1.0.2 27 | BuildRequires: pkgconfig(Qt5Core) 28 | BuildRequires: pkgconfig(Qt5Qml) 29 | BuildRequires: pkgconfig(Qt5Quick) 30 | BuildRequires: desktop-file-utils 31 | 32 | %description 33 | A Sailfish OS sample application written in Python. 34 | 35 | 36 | %prep 37 | %setup -q -n %{name}-%{version} 38 | 39 | # >> setup 40 | # << setup 41 | 42 | %build 43 | # >> build pre 44 | # << build pre 45 | 46 | %qtc_qmake5 47 | 48 | %qtc_make %{?_smp_mflags} 49 | 50 | # >> build post 51 | # << build post 52 | 53 | %install 54 | rm -rf %{buildroot} 55 | # >> install pre 56 | # << install pre 57 | %qmake5_install 58 | 59 | # >> install post 60 | # << install post 61 | 62 | desktop-file-install --delete-original \ 63 | --dir %{buildroot}%{_datadir}/applications \ 64 | %{buildroot}%{_datadir}/applications/*.desktop 65 | 66 | %files 67 | %defattr(-,root,root,-) 68 | %{_datadir}/%{name} 69 | %{_datadir}/applications/%{name}.desktop 70 | %{_datadir}/icons/hicolor/86x86/apps/%{name}.png 71 | # >> files 72 | # << files 73 | -------------------------------------------------------------------------------- /qml/cover/coveractions.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (C) 2015 Jolla Ltd. 5 | # Contact: Jussi Pakkanen 6 | # All rights reserved. 7 | # 8 | # You may use this file under the terms of BSD license as follows: 9 | # 10 | # Redistribution and use in source and binary forms, with or without 11 | # modification, are permitted provided that the following conditions are met: 12 | # * Redistributions of source code must retain the above copyright 13 | # notice, this list of conditions and the following disclaimer. 14 | # * Redistributions in binary form must reproduce the above copyright 15 | # notice, this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # * Neither the name of the Jolla Ltd nor the 18 | # names of its contributors may be used to endorse or promote products 19 | # derived from this software without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 25 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | 33 | def action_next(): 34 | return "Action\nnext\ntriggered." 35 | 36 | def action_pause(): 37 | return "Action\npause\ntriggered." 38 | -------------------------------------------------------------------------------- /qml/pythonsample.qml: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013 Jolla Ltd. 3 | Contact: Thomas Perl 4 | All rights reserved. 5 | 6 | You may use this file under the terms of BSD license as follows: 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of the Jolla Ltd nor the 16 | names of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | import QtQuick 2.0 32 | import Sailfish.Silica 1.0 33 | import "pages" 34 | 35 | ApplicationWindow 36 | { 37 | initialPage: Component { FirstPage { } } 38 | cover: Qt.resolvedUrl("cover/CoverPage.qml") 39 | } 40 | 41 | 42 | -------------------------------------------------------------------------------- /qml/cover/CoverPage.qml: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2015 Jolla Ltd. 3 | Contact: Thomas Perl 4 | All rights reserved. 5 | 6 | You may use this file under the terms of BSD license as follows: 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of the Jolla Ltd nor the 16 | names of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | import QtQuick 2.0 32 | import Sailfish.Silica 1.0 33 | import io.thp.pyotherside 1.4 34 | 35 | CoverBackground { 36 | Label { 37 | id: label 38 | anchors.centerIn: parent 39 | text: ("Plain Cover") 40 | } 41 | 42 | CoverActionList { 43 | id: coverAction 44 | 45 | CoverAction { 46 | iconSource: "image://theme/icon-cover-next" 47 | onTriggered: python.call('coveractions.action_next', [], function(newstring) { 48 | label.text = newstring; 49 | }); 50 | } 51 | 52 | CoverAction { 53 | iconSource: "image://theme/icon-cover-pause" 54 | onTriggered: python.call('coveractions.action_pause', [], function(newstring) { 55 | label.text = newstring; 56 | }); 57 | } 58 | } 59 | 60 | Python { 61 | id: python 62 | 63 | Component.onCompleted: { 64 | addImportPath(Qt.resolvedUrl('.')); 65 | importModule('coveractions', function () {}); 66 | } 67 | } 68 | } 69 | 70 | 71 | -------------------------------------------------------------------------------- /qml/pages/datadownloader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | # Copyright (C) 2015 Jolla Ltd. 5 | # Contact: Jussi Pakkanen 6 | # All rights reserved. 7 | # 8 | # You may use this file under the terms of BSD license as follows: 9 | # 10 | # Redistribution and use in source and binary forms, with or without 11 | # modification, are permitted provided that the following conditions are met: 12 | # * Redistributions of source code must retain the above copyright 13 | # notice, this list of conditions and the following disclaimer. 14 | # * Redistributions in binary form must reproduce the above copyright 15 | # notice, this list of conditions and the following disclaimer in the 16 | # documentation and/or other materials provided with the distribution. 17 | # * Neither the name of the Jolla Ltd nor the 18 | # names of its contributors may be used to endorse or promote products 19 | # derived from this software without specific prior written permission. 20 | # 21 | # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 22 | # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 23 | # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 25 | # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 26 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 27 | # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 28 | # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 30 | # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | # This file demonstrates how to write a class that downloads data from the 33 | # net, does heavy processing or some other operation that takes a long time. 34 | # To keep the UI responsive we do the operations in a separate thread and 35 | # send status updates via signals. 36 | 37 | import pyotherside 38 | import threading 39 | import time 40 | import random 41 | 42 | colors = ['red', 'orange', 'yellow', 'green', 'blue', 'indigo', 'violet'] 43 | 44 | def slow_function(): 45 | for i in range(11): 46 | pyotherside.send('progress', i/10.0) 47 | time.sleep(0.5) 48 | pyotherside.send('finished', random.choice(colors)) 49 | 50 | class Downloader: 51 | def __init__(self): 52 | # Set bgthread to a finished thread so we never 53 | # have to check if it is None. 54 | self.bgthread = threading.Thread() 55 | self.bgthread.start() 56 | 57 | def download(self): 58 | if self.bgthread.is_alive(): 59 | return 60 | self.bgthread = threading.Thread(target=slow_function) 61 | self.bgthread.start() 62 | 63 | 64 | downloader = Downloader() 65 | 66 | -------------------------------------------------------------------------------- /qml/pages/FirstPage.qml: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (C) 2013 Jolla Ltd. 3 | Contact: Thomas Perl 4 | All rights reserved. 5 | 6 | You may use this file under the terms of BSD license as follows: 7 | 8 | Redistribution and use in source and binary forms, with or without 9 | modification, are permitted provided that the following conditions are met: 10 | * Redistributions of source code must retain the above copyright 11 | notice, this list of conditions and the following disclaimer. 12 | * Redistributions in binary form must reproduce the above copyright 13 | notice, this list of conditions and the following disclaimer in the 14 | documentation and/or other materials provided with the distribution. 15 | * Neither the name of the Jolla Ltd nor the 16 | names of its contributors may be used to endorse or promote products 17 | derived from this software without specific prior written permission. 18 | 19 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 20 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR 23 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 28 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 | */ 30 | 31 | import QtQuick 2.0 32 | import Sailfish.Silica 1.0 33 | import io.thp.pyotherside 1.4 34 | 35 | Page { 36 | 37 | id: page 38 | property bool downloading: false 39 | 40 | PageHeader { 41 | id: header 42 | width: parent.width 43 | title: "Colorology app" 44 | } 45 | 46 | Label { 47 | id: mainLabel 48 | anchors.verticalCenter: parent.verticalCenter 49 | text: "Color is unknown." 50 | visible: !page.downloading 51 | anchors.horizontalCenter: parent.horizontalCenter 52 | } 53 | 54 | ProgressBar { 55 | id: dlprogress 56 | label: "Downloading latest color trends." 57 | anchors.verticalCenter: parent.verticalCenter 58 | width: parent.width 59 | visible: page.downloading 60 | } 61 | 62 | Button { 63 | text: "Update color" 64 | enabled: !page.downloading 65 | anchors.bottom: parent.bottom 66 | width: parent.width 67 | onClicked: { 68 | python.startDownload(); 69 | } 70 | } 71 | 72 | Python { 73 | id: python 74 | 75 | Component.onCompleted: { 76 | addImportPath(Qt.resolvedUrl('.')); 77 | 78 | setHandler('progress', function(ratio) { 79 | dlprogress.value = ratio; 80 | }); 81 | setHandler('finished', function(newvalue) { 82 | page.downloading = false; 83 | mainLabel.text = 'Color is ' + newvalue + '.'; 84 | }); 85 | 86 | importModule('datadownloader', function () {}); 87 | 88 | } 89 | 90 | function startDownload() { 91 | page.downloading = true; 92 | dlprogress.value = 0.0; 93 | call('datadownloader.downloader.download', function() {}); 94 | } 95 | 96 | onError: { 97 | // when an exception is raised, this error handler will be called 98 | console.log('python error: ' + traceback); 99 | } 100 | 101 | onReceived: { 102 | // asychronous messages from Python arrive here 103 | // in Python, this can be accomplished via pyotherside.send() 104 | console.log('got message from python: ' + data); 105 | } 106 | } 107 | } 108 | 109 | 110 | --------------------------------------------------------------------------------