python如何做成app?

Posted 幸运_39378260

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python如何做成app?相关的知识,希望对你有一定的参考价值。

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


python如何做成app?

工具:python-3.8.3-amd64.exe+kivy1.10.0+VirtualBox-6.1.34-150636-Win.exe
Kivy 是一套用于跨平台快速应用开发的开源框架,只需编写一套代码,便可运行于各大桌面及移动平台上(包括 Linux, Windows, OS X, android, ios, 以及 Raspberry Pi) Kivy 采用 Python 和 Cython 编写,在国外已经十分火爆,受关注程度甚至一度超越了老牌的 Python GUI 工具 PyQt。可惜 Kivy 在国内还鲜为人知。这一篇先教大家,在 Windows 上 安装 Kivy。
具体需要的工具都在百度网盘的名称为:python如何做成app的文件夹里

一、Python3.8.3版本+kivy1.10.0

1、安装python3.8.3
2、Cmd命令运行,查看python版本
Python --version
寻找python位置:where python
3、安装pycharm 2021.1
4、在pycharm里的文件-》设置-》python解释器:更改刚才安装的python3.8.3安装路径
如: C:\\Python38\\python.exe
5、在+号那安装查找kivy等各种依赖包#

二、用命令提示符(可cmd弹出)安装查找kivy等各种依赖包

1、请确保你的电脑上,已经安装了 Python 3.8.3, 并且已经设置好了 pip 国内源(国内镜像)。
2、设置匹配的国内镜像,可以让其他下载乃更快一点:
可以试试: pip install pip-setting
然后 pip-setting
3、通过命令安装virtualenv并创建虚拟环境。输入命令pip install virtualenv并执行。

4、输入命令python -m pip install --upgrade pip 升级pip版本。

5、执行成功后,可以查看升级是否成功。查看pip,输入命令pip show pip,
可以看到当前的pip版本已升级到20.2.3,可以进行下一步安装。

6、执行命令,生成虚拟环境:virtualenv testvir
7、在BISO里打开virtualenv

一、Windows 下安装 kivy

  1. 启动 Windows 命令行窗口(可直接在pycharm里文件-》设置-》python解释器-》在+号那安装查找kivy等各种依赖包安装)
    按 Windows 徽标 + R,输入 cmd,再按回车启动 Windows 命令行窗口
    二. pycharm安装 kivy 依赖**(和下面的pip 安装 kivy 依赖效果一致,用pycharm安装kivy的依赖包更加方便点**)
    可直接在pycharm里文件-》设置-》python解释器-》在+号那安装查找kivy等各种依赖包安装)
    1.分别查找:docutils、pygments、pypiwin32、sdl2、glew、gstreamer、image
    2、查找到之后,找到和下面的长得差不多的依赖包来安装就好,不一定就是一模一样(有的是横线代替小圆点)
    docutils、 pygments、 pypiwin32 、kivy.deps.sdl2 、kivy.deps.glew、
    kivy.deps.gstreamer、 image
    三. pip 安装 kivy 依赖
    在 windows 命令行中,执行以下命令:
    (1) python -m pip install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew
    (2) python -m pip install kivy.deps.gstreamer
    下面这个install image很多教程都没有。这个是我实操得出来的。
    (3)python -m pip install image
  2. 安装 kivy
    在 windows 命令行中,执行以下命令:
    python -m pip install kivy
  3. 安装 kivy 官方示例
    在 windows 命令行中,执行以下命令:
    python -m pip install kivy_examples

三、验证 kivy 安装

在 Python IDLE 或在pycharm里新建一个python文件:main.py,依次输入下面的代码:(注意缩进)

from kivy.app import App
from kivy.uix.button import Button

class TestApp(App):
def build(self):
return Button(text=‘iPaoMi’)

TestApp().run()
最后,你将看到执行上面的 Python 代码,会运行如下的窗口,这可以算是 kivy 版的 hello world 了。

或者下面的代码(是一个小孩子很喜欢的自由彩色画板):

from kivy.app import App
from kivy.uix.widget import Widget
from kivy.graphics import Color,Ellipse,Line
from random import random
from kivy.uix.button import Button

class MyWidgetWidget(Widget):
def on_touch_down(self, touch):
color=(random(),random(),random())
with self.canvas:
Color(*color)
touch.ud[‘Line’]=Line(points=(touch.x,touch.y),width=5)

def on_touch_move(self, touch):
    touch.ud['Line'].points=touch.ud['Line'].points+[touch.x,touch.y]

class MyPaintApp(App):
def build(self):
parent=Widget()
self.painter=MyWidgetWidget()
clearbtn=Button(text=“Clear”)
clearbtn.bind(on_release=self.clear_canvas)
parent.add_widget(self.painter)
parent.add_widget(clearbtn)
return parent

def clear_canvas(self,obj):
    self.painter.canvas.clear()

if name==‘main’:
MyPaintApp().run()

通过 kivy 提供的打包工具,你可以将 kivy 程序打包,运行到不同的平台上,包括各大主流的桌面系统和手机上(如 Android, iOS)。

**

四、安装上虚拟机VirtualBox

**
版本:VirtualBox-6.1.34-150636-Win.exe
1、下载VirtualBox-6.1.34-150636-Win.exe安装,下载Oracle_VM_VirtualBox_Extension_Pack-6.1.34.vbox-extpack,(Oracle_VM_VirtualBox_Extension_Pack-6.1.34.vbox-extpack存放到D盘的VirtualDisk文件夹)
2、安装上虚拟机VirtualBox后运行,然后直接双击Oracle_VM_VirtualBox_Extension_Pack-6.1.34.vbox-extpack就把这扩展安装上了(安装后可在VirtualBox-》管理-》全局设定-》扩展,即看见此扩展)。
在安装虚拟系统

3、建立共享文件夹
因为虚拟机无法和Windows直接交互,所以文件传输必须依靠共享文件夹进行)。

我在这里创建了一个VirtualDisk文件夹作为共享文件夹
【这一步可以理解为创建一个空白文件夹】,我们需要记住它的位置。在VirtualDisk文件夹里存放下载好的kivydev.ova

(我这里在D盘里新建了三个文件夹,virtualbox文件夹用来安装VirtualBox-6.1.34-150636-Win.exe,VirtualDisk文件夹用来存放kivydev.ova和Oracle_VM_VirtualBox_Extension_Pack-6.1.34.vbox-extpack,virtualbox_system文件夹用来存放安装kivydev.ova系统的虚拟系统盘)

4、导入kivydev.ova系统
安装完成的虚拟机是没有任何系统的,此时需要导入kivydev.ova系统。
在【管理】菜单下,点击【导入虚拟电脑】
选择下载好的kivydev.ova文件

注意:在安装虚拟系统盘时出现安装不上去的情况,返回 代码: E_INVALIDARG (0x80070057)解决方法
导入
可能是一开始安装了一下,然后取消安装了。
举个例子,我是直接导入的,一开始忘记修改虚拟机路径了,然后就点了装,然后被我取消了,然后去别的地方安装的时候,就出现了
返回 代码: E_INVALIDARG (0x80070057)的错误,然后我找到了之前的默认路径,把之前取消安装的残余给删掉了,然后我又打开了打开VirtualBox管理器(重新安装VirtualBox-6.1.34-150636-Win.exe)**
安装好虚拟系统盘如下图所示:

5、配置虚拟机
点击设置,进入虚拟机的设置界面,然后找到最下面的【共享文件夹】,点击右边的加号,添加共享文件夹位置。

粘贴我们之前创建的【共享文件夹】位置,将【自动挂载】打勾,点击确定,配置完成。

五、编辑一个kivy程序进行测试
(我们已经完成了kivy安装和虚拟机部分的安装,接下来就要把pycharm里运行好的main.py,放在虚拟机内进行调用,进行打包测试。)

六、打包成Apk文件
1、打开我们创建完成的虚拟机。点击启动,耐心等待到进入Linux桌面。

2、打开桌面的File System,接着点击左边栏sf_VirtualDisk(我们之前创建的共享文件夹)。里面有我们保存的"main.py"和"kivydev.ova"。

注意:进去系统后发现没有看见共享文件夹,怎么办?
办法如下:
oracle VM virtualbox安装增强功能与设置全屏

虚拟机:VirtualBox
要使用全屏和共享等功能需要为虚拟机安装增强功能>>

点击"设备"–>“安装增强功能”

桌面上会出现光驱图标,VBOXADDITIOINS_3.28_64453,如果没有也可以在media文件夹中去找
(2)安装增强功能

打开它,找到里面的VBoxLinuxAdditions-x86.run

打开终端,进入到 cd /media/VBOXADDITIONS_XXX写上以下命令:
# sh VBoxLinuxAdditions.run 运行丫的(不需要#号)

到此,增强功能安装完毕, reboot
(3)现在在虚拟系统里可以看见共享文件夹

3、点击左边栏kivydev目录下找到kivy,在kivy目录下进入accordion。再将"main.py"复制到当前目录下(即**/home/kivydev/kivy/accordion/**目录下)。它会覆盖此目录下的示例——一个main.py文件。因为打包的时候,主程序的名字都是main.py。

右击空白区域,打开 Open Terminal Here命令框。


(如果目录下没有buildozer.spec文件,执行这一步)在此框内键入以下代码,生成一个buildozer.spec文件

buildozer init


接着再输入命令,打开buildozer.spec文件,主要修改Title(应用名字,我设置为SamplePainter),package.name(打包名,同样设置成SamplePainter),package.domain(打包成哪一种ios或者安卓,这里我不改,默认打包成安卓文件)。
其余的建议暂时不要修改。
修改完成后保存 Save,关闭文件,回到命令框。

gedit buildozer.spec

在命令框内键入:

buildozer android_new debug

进行打包,此过程需要等待几分钟。

打包完成,按照提示的地址寻找打包后的文件。

关闭命令框,在bin文件夹下看见我们的应用SamplePainter,另一个MyApplication是示例文件,不予理会。

把这个文件复制到共享文件夹内。

七、发送到手机并安装
回到Windows,打开我们的共享文件夹VirtualDis,可以看见创建的SamplePainter.apk文件。

把文件发送到手机,【注意】如果文件名后缀不是apk,请手动重命名为apk后缀。安装到手机。
在这里插入图片描述,用手机打开App,可看到效果。

总结

   在cmd里安装kivy会产生很多和版本不一的问题,建议大家下载的python版本要和此文一致,记得 升级pip版本,cmd里运行:python -m pip install --upgrade pip,直接用pycharm安装kivy等各种依赖包安装比较方便。

  注意:该文章有部分来源于网页上各位前辈的文章和自己的实操,如有侵权行为,请联系本人。

参考资料:
1、 来自“ 海底捞淡水鱼” ,链接: https://blog.csdn.net/qq_37030400/article/details/107620264
2、来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/29674916/viewspace-2086547/,
如需转载,请注明出处,否则将追究法律责任。

用angular7+Ionic做移动App做成了webapp引发的系列问题

背景:公司前端开发一直使用angular,后公司想开发移动app应用,便考虑使用Ionic+angular使用。项目快结束时上级领导决定不做app,做移动端适配,emmm.....

大的问题不说了,网上都有,说下遇到的奇葩需求;由于使用Ionic框架,用一个做app的框架做了移动端适配,总是有点感觉在浏览器里面套了一个浏览器在装我们的页面,web原来是div高度撑出浏览器显示高度浏览器出现滚动条,但是使用这个确认Ionic有自己的想法,看前端的层级目录发现,在body下上来就是app-root根路径,根路径下就是ion-app,而这个ion-app就限定了高度和手机屏幕高度一致,如图(1-1)所示,即无论ion-app里面页面高如如何都不可能撑出浏览器高度,都会在里面出现滚动条,即对于部分浏览器支持当页面高度撑出浏览器后下滑隐藏浏览器功能键使用该开发的移动web端无法实现,单是需求就是:在不改变使用框架的情况下需要实现下拉隐藏浏览器功能菜单功能;尽管心中一万草泥马在奔腾,但还是要做;

技术图片

                                                    图(1-1)

思路既然是该ion-app限制了高度,是的内部的ion-content也与其高度保持了一致,那么我将ion-app的高度设置成当前页面的高度,则就可以撑出浏览器高度,如果使用浏览器滚动功能,则需要禁用掉ion-content的在竖直方向上的滚动;

code:

  目录层级:技术图片  技术图片 技术图片

       ts代码: 

    

declare const document: any;

export class XXXXX implements OnInit, OnDestroy 
   isLeave = true;
   constructor()
   ngOnInit()...
    

ionViewWillLeave() 
        this.isLeave = false;
        document.getElementById("ion-app-auto-height").style.height = ‘100%‘;
    

    ionViewDidEnter() 
        if (!this.isLeave) 
            let offsetHeight = document.getElementById("product-detail-t").offsetHeight + ‘px‘;
            document.getElementById("ion-app-auto-height").style.height = offsetHeight;
            this.isLeave = true;
        
    

    ngAfterViewChecked() 
        if (document.getElementById("product-detail-t").offsetHeight != 0) 
            let offsetHeight = document.getElementById("product-detail-t").offsetHeight + ‘px‘;
            if (document.getElementById("ion-app-auto-height").style.height !== offsetHeight) 
                if (this.isLeave) 
                    document.getElementById("ion-app-auto-height").style.height = offsetHeight;
                
            
        
    

注意上述代码标红的位置需要替换成html中ion-app定义的id以及当前页面最外层div定义的id;

特别注意:body需要设置一下属性,否则会导致撑出页面隐藏;

body
  position: unset;
  overflow: auto

页面渲染完成,将当前页面div的高度赋值值ion-app的高度,禁用ionic的滚动功能,并且页面撑出浏览器,便可顺利实现需求(在iso和android测试均通过);

 

问题2:由于改变了展示方式,导致了之前的浏览器滚动到底在在数据无法使用,即ion-infinite-scroll控件失效,这里自己写了一个控件来实现:

 2.1目录结构: 技术图片

   html内容:功能占位

<p></p>

  scss内容:空

  ts文件内容:

import Component, HostListener, Input, OnDestroy, OnInit from ‘@angular/core‘;
import TablePageService from ‘../table-page/table-page.service‘;
import TablePageParams from ‘../table-page/table-page.service‘;
import debounceTime, take from ‘rxjs/operators‘;
declare const document: any;

@Component(
  selector: ‘app-infinite-scroll‘,
  templateUrl: ‘./infinite-scroll.component.html‘,
  styleUrls: [‘./infinite-scroll.component.scss‘]
)
export class InfiniteScrollComponent implements OnInit
    @Input() service: TablePageService<any>;
    @HostListener(‘window:scroll‘, [‘$event‘]) public onScroll = ($event) => 
        //客户端高度
        var clientH = document.documentElement.clientHeight*1;
        //body高度
        var bodyH = document.getElementById("ion-app-auto-height").style.height.replace(‘px‘,‘‘)*1;
        //滚动的高度
        var scrollTop = (document.documentElement.scrollTop || document.body.scrollTop || window.pageYOffset)*1;
        //滚动到底部60以内
        if ((bodyH - clientH - scrollTop)*1 < 100) 
            if (!this.flag) 
                if (!this.isLast) 
                    this.query();
                
            
            this.flag = true;
         else 
            this.flag = false;
        
    
    flag = false;
    isLast = false;
    type = ‘01‘;
    private data: any[] = [];
    private tablePageParams: TablePageParams;
    constructor()  

  ngOnInit() 
      this.service.params.pipe(debounceTime(200)).subscribe(params => 
        if (this.type != params.type) 
          this.type = params.type;
          this.flag = false;
          this.isLast = false;
        
          this.tablePageParams = new TablePageParams(params, 1);
          this.data = [];
          this.query();
      );
  
    query() 
        this.service.queryPage(this.tablePageParams)
            .pipe(take(1))
            .subscribe(result => 
                this.tablePageParams.pageNumber++;
                this.data = this.data.concat(result.result);
                this.service.result.next(this.data);
                if (result.currentPageNo === result.totalPageCount || this.data.length > 500) 
                  this.isLast = true;
                
            );
    

  前端定义的TablePageService接口:

import Subject, ReplaySubject, Observable from ‘rxjs‘;

export abstract class TablePageService<T> 
    result = new Subject<T[]>();
    params = new ReplaySubject<any>();

    constructor() 
    

    query(params = ) 
        this.params.next(params);
    

    complete() 
        this.result.complete();
        this.params.complete();
    

    abstract queryPage(params: TablePageParams): Observable<TablePageResult<T>>;
export class TablePageParams 
pageNumber: number;
pageSize: number;
params: any;
totalPage: number;

constructor(_params: any = , _pageNumber = 1, _pageSize = 20, _totalPage = 1)
this.params = _params;
if (typeof _pageNumber !== ‘number‘)
_pageNumber = parseInt(_pageNumber, 20);

this.pageNumber = _pageNumber > 0 ? _pageNumber : 1;
this.pageSize = _pageSize;
this.totalPage = _totalPage;



export class TablePageResult<T>
currentPageNo = 1;
pageSize = 20;
result: T[];
totalCount = 0;
totalPageCount = 1;

constructor()

exports出该控件;

 2.2 控件使用:

在html中引入控件,并传入service;

    技术图片

在ts文件中,定义该service,

ts文件:

import Component, OnDestroy, OnInit from ‘@angular/core‘;
import Subscription from ‘rxjs/index‘;
import OrderProductInfo from ‘../../../core/aftersales-core/domain/orderform‘;
import AftersalesTablePageService from ‘../aftersales-table-page.service‘;
import AfterSalesIndexService from ‘../index/after-sales-index-service‘;
declare const document: any;

@Component(
    selector: ‘app-aftersales-apply‘,
    templateUrl: ‘./aftersales-apply.component.html‘,
    styleUrls: [‘./aftersales-apply.component.scss‘],
    providers: [AftersalesTablePageService]
)
export class AftersalesApplyComponent implements OnInit, OnDestroy 

    orderProductList: OrderProductInfo[] = [];
    private subscriptions: Subscription[] = [];
    isLeave = true;

    constructor(public tableService: AftersalesTablePageService) 
    

    ngOnInit() 
        const pageSub = this.tableService.result.asObservable().subscribe(result =>    //监听result数据的变化
            this.orderProductList = result as [];
        );
        this.subscriptions.push(pageSub);
        this.query();
    

    query() 
        this.tableService.query();
    

    ngOnDestroy(): void 
        this.subscriptions.forEach(_item => _item.unsubscribe());
    

    ionViewWillLeave() 
        this.isLeave = false;
        document.getElementById("ion-app-auto-height").style.height = ‘100%‘;
    

    ionViewDidEnter() 
        if (!this.isLeave) 
            let offsetHeight = document.getElementById("aftersales-apply-t").offsetHeight + ‘px‘;
            document.getElementById("ion-app-auto-height").style.height = offsetHeight;
            this.isLeave = true;
        
    

    ngAfterViewChecked() 
        
            if (document.getElementById("aftersales-apply-t").offsetHeight != 0) 
                let offsetHeight = document.getElementById("aftersales-apply-t").offsetHeight + ‘px‘;
                if (document.getElementById("ion-app-auto-height").style.height !== offsetHeight) 
                    if (this.isLeave) 
                        document.getElementById("ion-app-auto-height").style.height = offsetHeight;
                    
                
            
        
    

实现service代码示例,具体查询某一接口:

@Injectable(
    providedIn: null
)
export class AftersalesTablePageService extends TablePageService<any> 

    constructor(private table: TableService) 
        super();
    

    queryPage(tablePageParams: TablePageParams) 
        return this.table.queryPage<OrderProductInfo>(‘/orderform/getorderproductpage.do‘, tablePageParams);
    


  tableService,具体http请求以及返回数据的封装;

技术图片

 

  最终效果:

          技术图片

   实现距离底部100px,加载新数据;

以上是关于python如何做成app?的主要内容,如果未能解决你的问题,请参考以下文章

python利用python制作通讯录管理系统

如何输入多索引熊猫数据框 Python3.8+ 的提示?

安装好Pycharm后如何配置Python解释器简易教程

selenium环境搭建

H5平台如何做成APP?

Windows安装python3.x和pythcharm