Kivy tutorial 004: Making the GUI do stuff, binding to events

Kivy tutorial 004: Making the GUI do stuff, binding to events – Kivy Blog

Central themes: Events and Kivy properties
中心主题:事件和kivy属性

We left the last tutorial with a calculator app GUI with some nice automatic behaviour, but which doesn’t actually do anything. Let’s change that; it’s time to learn about binding events.
上次导师课我们留下了一个有着一些不错的自动行为的计算机GUI,但是这真是啥也不干。让我们改变它,是时候了解绑定事件了。

To refresh, the basic calculator GUI code was as follows. If you modified it to experiment, feel free to continue with your modified code, and try to change the instructions to fit your modifications:
为了重新刷新,基本的计算机GUI代码像下面一样。如果你修改它来体验,随意继续修改你的代码,并且试着改变结构来达到你的修改。

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label


class YourApp(App):
    def build(self):
        root_widget = BoxLayout(orientation='vertical')

        output_label = Label(size_hint_y=1)

        button_symbols = ('1', '2', '3', '+',
                          '4', '5', '6', '-',
                          '7', '8', '9', '.',
                          '0', '*', '/', '=')

        button_grid = GridLayout(cols=4, size_hint_y=2)
        for symbol in button_symbols:
            button_grid.add_widget(Button(text=symbol))

        clear_button = Button(text='clear', size_hint_y=None,
                              height=100)

        root_widget.add_widget(output_label)
        root_widget.add_widget(button_grid)
        root_widget.add_widget(clear_button)

        return root_widget


YourApp().run()

Note

This tutorial introduces some major new Kivy concepts. I recommend working through it even if you don’t entirely follow what’s going on, then going back to modify components and see how things change.
这节导师课介绍一些主要的kivy概念。 我建议克服它尽管你没有整个的跟随事态的进行,然后返回修改部件并且看看事如何改变的。

The plan now is that every one of these buttons should add their symbol to the Label at the top, except ‘=’ which should evaluate the code and display the result. This is obviously an extremely basic calculator, but the point here is to showcase some Kivy basics - if you’d like to improve the interface, go ahead with trying to do so along the way.
现在的计划是每个按钮应该增加他们的符号到标签的上面, 除了=号应该求值并且展示结果。这是一个极其明显的基础的计算机,但是这的关键点是展示一些kivy的基本要素-如果你想来提升界面,继续沿着这种方式继续尝试。

To make the buttons do something, we must bind to their events. This is a generic Kivy concept; whenever you want one thing to trigger another, you look for an event to bind to. Some widgets such as Button have events indicating they have been clicked on, and every Kivy property (such as all those used to customise Widgets so far) has an associated event when it changes.
为了让按钮做点事,我们必须bind绑定给它们的事件。这是一个通用kivy概念,当你像一个事引发另一个事的时候,你寻找一个事件来帮i的那个。一些组件例如Button按钮有些事件表明它们已经被点击了,并且每个kivy属性(例如所有的这些都是被用来自定义组件)有一个关联事件当它改变时。

Let’s start with a simple binding example: 让我们开始一个简单地bind绑定案例:

def print_button_text(self, instance):
    print(instance.text)
for button in button_grid.children[1:]:  # note use of the
                                         # `children` property
    button.bind(on_press=print_button_text)

# we could also have used `button.bind(on_press=lambda instance: print(instance.text))`

If you run the code now, and click on any of the buttons, you should see its text printed in the console (but not in the Kivy GUI).
如果你现在运行代码,并且点击任何按钮,你应该看见它的text信息在console控制台中打印出来(不是在KIVY的GUI中)

The key concept here is the bind method, which you can use with any Widget, as well as several other Kivy objects (discussed in later tutorials). This takes any number of keyword arguments, each specifying an event name and a function to call; in this case the event name is on_press, and the function to be called is our new print_button_text`. The ``bind` method makes sure that whenever on_press occurs, the function is called. It automatically receives a single argument, the binded widget instance.
这儿的主要概念是绑定方法, 你可以同任何组件使用绑定方法,和好几个个其他的kivy对象(之后的导师课会有涉及)。这携带任何关键字的元素,每个关键字元素特别说明一个event事件名字和一个功能来召唤;在情况下,event事件名字是 on_press, 并且  被使唤的功能是 我们的print_button_text。  bind 方法确保当 on_press出现时,功能被使唤。 它自动地接收一个单一的变量,这变量时被绑定的组件实例。

Also note that we’ve iterated over button_grid.children[1:]`. The ``children` property is available on any Widget, and holds a list of all the widgets added to it, in reverse order. In this case, we use [1:] to skip the first element, ‘=’, as we want to use this to evaluate the result.
也请注意我们已经和button_grid.children[1:]互动了。  子类属性在任何组件中都适用,并且包含了一个所有组件添加其中的list列表,这列表是反序的。在这种情况下,我们使用[1:] 来跳过第一个元素, '='向我们想的一样使用这玩意来求结果的值。

Note

Button also has an on_release event that is called when the user releases a click or touch. You can find more information in the Button documentation.
按钮也有一个on_release事件,当一个用户松开一个点击或者触摸 这on_release事件被使唤。你可以发现更多的信息在 Button文档中。

This binding idea is very normal in Kivy, and you’ll quickly get used to seeing it used in different ways, including some introduced later in these tutorials. The kv markup language, also introduced later, has special syntax designed to make it even simpler and clearer.
在kivy 绑定想法非常常见,并且你可以快速地习惯来看它在不同的方式中使用。在之后的导师课中会有介绍。 kv 标记语言, 也在之后被介绍, 有特殊地语法被设计来让代码更简单和更清晰。

Anyway, all this does so far is print some text when the event occurs, but we want to update the GUI. Let’s change the bound function to achieve that:
无论如何,所有干的这些当目前为止是,当事件出现时打印了一些文本,但是我们想要更新GUI。 让我们改变被捆绑的功能来实现它:

def print_button_text(instance):
    output_label.text += instance.text

Run the code again. Now when you press the buttons, you should see the text appear at the top of the screen, as in the screenshot below:
再次运行代码。现在当你按按钮,你应该看到文本出现在屏幕地商法,像下面截图一样:

Calculator text after number input

At this point, a new problem presents itself; the font size of the label is kind of small. We can use another event to have it update automatically in response to the label’s height:
在这时,一个新的问题它自己出现了;标签地大小有点小了。我们可以使用另一个事件来让它自动地更新来响应标签的高度:

def resize_label_text(label, new_height):
    label.font_size = 0.5*label.height
output_label.bind(height=resize_label_text)

Note that the event here is named height. This works because the Label has a Kivy property named height (as do all Widgets, see the documentation, and all Kivy properties can be bound to as an event of the same name, called when the property changes. In this case, you can now resize the window, which causes the layouts in the Widget tree to automatically resize their children, which in turn causes resize_label_text to automatically be called.
注意现在这地事件被命名为高度。 这行, 因为Label标签有一个kivy属性被叫做height高度(所有的组件都这么干,看文档, 所有的kivy属性可以被绑定作为一个这相同名字的事件,当属性改变时被叫唤。在这种情况下,你现在可以重新定义窗口的大小,这也导致了布局里的组件树自动地定义它的子类大小,这也相继地导致  resize_label_text 自动地被使唤。

We’ll use one final binding to make the calculator interface actually work; when the ‘=’ button is pressed, we can evaluate the entire label text as python code, and display the result.
我们将使用一个最终的绑定来使计算机界面真实起效;当= 号按钮被按下时,我们可以求出整个label标签里的值作为python代码,并且展示结果。

Note

Using eval as a calculator like this is in general a terrible idea, used here only to avoid dwelling on the details rather than the Kivy principles.

像这样使用eval求值  作为计算器通常是一个糟糕的想法,这里使用它只是为了避免纠缠于细节而不是Kivy原则。

def evaluate_result(instance):
    try:
        output_label.text = str(eval(output_label.text))
    except SyntaxError:
        output_label.text = 'Python syntax error!'
button_grid.children[0].bind(on_press=evaluate_result)
# Remember, button_grid.children[0] is the '=' button

Further, we can make the ‘clear’ button clear the label, so that you can start a new calculation:

另一方面我们使 clear按钮清空label 标签,因此可以开始一个新的计算:

def clear_label(instance):
    output_label.text = ''
clear_button.bind(on_press=clear_label)

With this all in place, run the app again and…the calculator works! Every button now does something, either adding its symbol to the output label, evaluating the label’s text as python code, or clearing the result. You should be seeing something like the image below:

这些就绪以后,再次运行app... 计算机运行了!  现在每个按钮干了些事,要么添加他的符号给输出标签, 求作为python代码的标签文本值, 或者清空结果。 你应该看像下面图片一样的事儿:

Output for calculator app with number input

These core event binding concepts are central to working with Kivy widgets, and come up in many different ways. Don’t worry if you don’t remember all the details straight away, such as the way all properties have events you can bind to, or the specific syntax; you can look all this up in the documentation as linked throughout and indexed on the Kivy website. Later tutorials also follow on to help cement this knowledge.
这些代码绑定概念是kivy组件的核心,并且以不同的方式出现。 如果你不能立即记得所有的细节,例如所有的属性都可以由你绑定的事件, 或者特殊的语法; 你可以在文档中查询这所有的全部,就像在文中超链接所示。等会导师课跟随着帮助加强知识。

Full code

your_filename.py:

from kivy.app import App
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label


class YourApp(App):
    def build(self):
        root_widget = BoxLayout(orientation='vertical')

        output_label = Label(size_hint_y=1)

        button_symbols = ('1', '2', '3', '+',
                          '4', '5', '6', '-',
                          '7', '8', '9', '.',
                          '0', '*', '/', '=')

        button_grid = GridLayout(cols=4, size_hint_y=2)
        for symbol in button_symbols:
            button_grid.add_widget(Button(text=symbol))

        clear_button = Button(text='clear', size_hint_y=None,
                              height=100)

        def print_button_text(instance):
            output_label.text += instance.text
        for button in button_grid.children[1:]:  # note use of the
                                             # `children` property
            button.bind(on_press=print_button_text)

        def resize_label_text(label, new_height):
            label.font_size = 0.5*label.height
        output_label.bind(height=resize_label_text)

        def evaluate_result(instance):
            try:
                output_label.text = str(eval(output_label.text))
            except SyntaxError:
                output_label.text = 'Python syntax error!'
        button_grid.children[0].bind(on_press=evaluate_result)

        def clear_label(instance):
            output_label.text = ''
        clear_button.bind(on_press=clear_label)

        root_widget.add_widget(output_label)
        root_widget.add_widget(button_grid)
        root_widget.add_widget(clear_button)

        return root_widget


YourApp().run()

eval

Python eval() 函数 | 菜鸟教程

困惑: button_grid.children[0].bind(on_press=evaluate_result),为啥用这布局中的第一个元素绑定str后的eval后的值呢?为啥不是第二个值呢?

我溜达了半天,人家文中说的很明白,children这玩意与生俱来,并且是in reverse order!反序!

也就是说,根据咱添加按钮的顺序,button_grid.children[0]是什么呢?

我1开始在代码中添加了

print(button_grid.children)

结果是

[<kivy.uix.button.Button object at 0x00000163EA850510>, <kivy.uix.button.Button object at 0x00000163EA850200>, <kivy.uix.button.Button object at 0x00000163EA810EB0>, <kivy.uix.button.Button object at 0x00000163EA810BA0>, <kivy.uix.button.Button object at 0x00000163EA810890>, <kivy.uix.button.Button object at 0x00000163EA810580>, <kivy.uix.button.Button object at 0x00000163EA810270>, <kivy.uix.button.Button object at 0x00000163EA7D4F20>, <kivy.uix.button.Button object at 0x00000163EA7D4C10>, <kivy.uix.button.Button object at 0x00000163EA7D4900>, <kivy.uix.button.Button object at 0x00000163EA7D45F0>, <kivy.uix.button.Button object at 0x00000163EA7D42E0>, <kivy.uix.button.Button object at 0x00000163E01DBF90>, <kivy.uix.button.Button object at 0x00000163E01DBC80>, <kivy.uix.button.Button object at 0x00000163E01DB970>, <kivy.uix.button.Button object at 0x00000163E01DB5F0>]

这谁能看懂,也不知道咋处理,那反序的话不就是咱最后添加的按钮,  =号嘛

人家把算好的结果绑定给 等于号=怎么了? 不就是绑定给=等于号吗? XDD

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/744349.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式C语言中常见寄存器的控制方法

使用C语言对寄存器赋值时,常常需要用到C语言的位操作方法。 把寄存器某位清零 假设a代表寄存器,且其中本来已有值。如果要把其中某一位清零且其它位不变,代码如下。 //定义一个变量 a = 1001 1111 b (二进制数)unsigned char a = 0x9f;//对 bit2 清零a &= ~(1<<…

实现批量自动化电商数据采集|商品详情页面|店铺商品信息|订单详情数据

电商数据采集是指通过技术手段获取电商平台上的商品信息、店铺信息和订单信息等数据。这些数据可以用于市场分析、竞品分析、用户行为分析等。 商品详情页面是指电商平台上展示商品详细信息的页面&#xff0c;包括商品名称、价格、图片、描述、评价等信息。通过采集商品详情页…

springboot+vue+mybatis门窗管理系统+PPT+论文+讲解+售后

如今社会上各行各业&#xff0c;都在用属于自己专用的软件来进行工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。互联网的发展&#xff0c;离不开一些新的技术&#xff0c;而新技术的产生往往是为了解决现有问题而产生的。针对于仓库信息管理方…

[学习笔记] 禹神:一小时快速上手Electron笔记,附代码

课程地址 禹神&#xff1a;一小时快速上手Electron&#xff0c;前端Electron开发教程_哔哩哔哩_bilibili 笔记地址 https://github.com/sui5yue6/my-electron-app 进程通信 桌面软件 跨平台的桌面应用程序 chromium nodejs native api 流程模型 main主进程 .js文件 node…

攻克PS之路——Day1(A1-A8)

#暑假到了&#xff0c;作为可能是最后一个快乐的暑假&#xff0c;我打算学点技能来傍身&#xff0c;首先&#xff0c;开始PS之旅 这个帖子作为我跟着B站up主学习PS的记录吧&#xff0c;希望我可以坚持下去&#xff01; 学习的链接在这里&#xff1a;A02-PS软件安装&#xff0…

Qt | 子类化 QStyle(Qt自带图标大全)

01、简介 1、把绘制自定义部件外观的步骤大致分为三大板块,如下: ①、样式元素:即指定需要绘制的图形元素(比如焦点框、按钮,工具栏等)。样式元素使 用 QStyle 类中的一系列枚举(共有 11 个枚举)进行描述。 ②、样式选项:包含了需要绘制的图形元素的所有信息,比如包含…

【QCustomPlot实战系列】QCPGraph区域高亮

使用QCPDataSelection来设置选中的区域&#xff0c;并将QCPGraph的可选择区域设置成QCP::stMultipleDataRanges void AreaPieces::initCustomPlot(QCustomPlot *parentPlot) {QVector<double> x {0, 1, 2, 3, 4, 5, 6, 7, 8};QVector<double> y {200, 560, 750…

asp.net core反向代理

新建项目 新建空白的asp.net core web项目 安装Yarp.ReverseProxy包版本为2.2.0-preview.1.24266.1 编写代码 namespace YarpStu01;public class Program {public static void Main(string[] args){var builder WebApplication.CreateBuilder(args);builder.Services.AddRev…

昇思25天学习打卡营第01天|基本介绍

作为曾经的javaer&#xff0c;本着不断学习的初心&#xff0c;报名了昇思25天的课程&#xff0c;希望自己能学会点东西的目的。 昇思MindSpore介绍 昇思MindSpore是一个全场景深度学习框架&#xff0c;旨在实现易开发、高效执行、全场景统一部署三大目标。 其中&#xff0c;…

AI大模型日报#0625:OpenAI停止不支持国家API、大模型「考上」一本、苹果上新视觉模型4M-21

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE-4.0-8K-latest&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xff01;《AI大模型日报》今日要点&#xf…

【LeetCode】一、数组相关(双指针算法 + 置换)

文章目录 1、算法复杂度1.1 时间复杂度1.2 空间复杂度 2、数组3、leetcode485&#xff1a;最大连续1的个数4、leetcode283&#xff1a;移动05、leetcode27&#xff1a;移除元素 1、算法复杂度 1.1 时间复杂度 算法的执行时间与输入值之间的关系&#xff08;看代码实际总行数的…

MySQL 5.7.42 主从复制环境搭建

MySQL 5.7.42 主从复制环境搭建 下载MySQL二进制包操作系统环境配置安装过程搭建从库 本次安装环境&#xff1a; OS版本&#xff1a;Red Hat Enterprise Linux Server release 6.8 (Santiago) MySQL版本&#xff1a;5.7.42 架构&#xff1a;同一台机器&#xff0c;多实例安装搭…

洁净室(区)浮游菌检测标准操作规程及GB/T 16292-2010测试方法解读

洁净室(区)空气中浮游菌的检测。洁净区浮游菌检测是一种评估和控制洁净区(如实验室、生产车间等)内空气质量的方法。这种检测的目的是通过测量空气中的微生物(即浮游菌)数量&#xff0c;来评估洁净区的清洁度或污染程度。下面中邦兴业小编带大家详细看下如何进行浮游菌采样检测…

TSLANet:时间序列模型的新构思

实时了解业内动态&#xff0c;论文是最好的桥梁&#xff0c;专栏精选论文重点解读热点论文&#xff0c;围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调或者LLM背后的基础模型重新阅读。而最新科技&#xff08;Mamba,xLSTM,KAN&#xff09;…

Python --- 如何修改Jupyter Notebook保存文件的路径?

如何修改Jupyter Notebook在本地保存文件的默认路径&#xff1f; 一直以来都比较喜欢jupter notebook&#xff0c;自从用了以后就爱上了。平时用的时候&#xff0c;因为大多都是临时调用&#xff0c;每次在界面里直接new一个新的file就开干。 曾经也想过我创建的这些python文件…

Android开发系列(十)Jetpack Compose之Card

Card是一种常用的UI组件&#xff0c;用于显示一个具有卡片样式的容器。Card组件通常用于显示列表项、卡片式布局或任何需要显示边框和阴影的UI元素。 使用Card组件&#xff0c;您可以轻松地创建带有卡片效果的UI元素。以下是一些Card组件的常见属性和功能&#xff1a; elevati…

微软专家分享 | AIGC开发者沙龙上海站来啦!

为了向技术开发者、业务人员、高校学生、以及个体创业人员等AI技术关注者们提供更深入的行业洞察、技术交流平台和创新思维的启发&#xff0c;AIGC开放社区联合微软Reactor特别组织了一系列城市巡回沙龙分享活动。在上海站中&#xff0c;我们有幸邀请到多位微软专家进行深入的主…

操作系统实训复习笔记(第7关:生产者消费者问题实践)

目录 第7关&#xff1a;生产者消费者问题实践 第1关&#xff1a;生产者消费者问题实践 1、在主线程中初始化锁为解锁状态 2、访问对象时的加锁操作与解锁操作 3、&#xff08;生产和消费进程操作后&#xff09;信号量操作实现进程同步 4、先等待&#xff08;生产还是消费…

数字孪生为何在智慧工业中备受青睐

数字孪生在智慧工业中为何愈发受到重视&#xff1f;随着工业4.0时代的到来&#xff0c;制造业正经历着前所未有的变革。数字孪生技术作为一项革新性的科技手段&#xff0c;通过构建物理实体的数字化复制品&#xff0c;为工业生产、管理和优化提供了全新的方法和视角。其独特的优…

使用Servlet开发javaweb,请求常见错误详解及其解决办法【404、405、500】

Servlet报错的情况多种多样&#xff0c;涵盖了配置错误、代码逻辑错误、资源未找到、权限问题等多个方面。以下是一些常见的Servlet报错情况及其可能的原因和解决方法&#xff1a; 404 Not Found: 错误原因图示&#xff1a; URL映射 发送请求&#xff0c;出现404错误 原因: 请…