PyQt5教程2:主页面和拖动
这一篇文章中,我们要实现的是主界面和主界面上需要支持的一些功能,我们将使用Qt Creator来创建我们的基本主界面。
1. UI设计
打开Qt Creator,在文件菜单中选择“新建文件或项目”,因为我们只是用Qt Creator来设计UI,所以我们只用它来创建和编辑.ui文件。我们在弹出的界面中选择Qt Designer Form,点击“Choose”

在随后弹出的窗口中,工具提供了一些常用的界面模板,因为我们是在做工具的主界面,因此一般选择Main Window

然后将ui文件保存到我们的项目目录,可以沿用它给的默认名称或者按照需要修改,点击下一步以后,可以选择使用Git作为版本控制,再次,我们只是希望使用Qt Creator作为一个ui设计工具,而版本控制,我们会自己使用Git来做,所以不需要添加到版本控制系统。然后工具就会加载工作区,如下图,工具有几个重要的区域,后边的设计中会一直用到,如果你之前实用过visual studio做过Windows桌面应用开发的话,这个界面很类似的。
- 首先是会在左上角显示我们正在修改的文件,同时也可以切换我们要修改的文件
- 然后在它的下方是预置的常用控件,基本上设计一个界面美观度要求不高,重实用的桌面应用,实用这些控件就足够了
- 在工具的正中央就是我们的界面画布,一个全新的主窗口会包含一个空的菜单栏,可以添加像文件、编辑、设置、帮助等等这些常用的菜单以及相应的子菜单,主窗口最底下是一个空的状态栏。菜单栏和状态栏中间就是我们的主界面本身,我们将在上边添加需要的各种各样的控件。
- 在工具的右上方是对象窗口,用于选中我们画好的控件
- 在对象窗口下方是控件属性窗口,可以修改各式各样的控件属性,这些属性都可以通过修改源代码来动态的更改,这里设置的是初始值,有时候很多属性我们只需要一个初始值,而不需要动态的更新,那么通过这样一个人性化的设计界面,则可以直观快速的修改

了解了这些基本概念之后,我们来给我们的WiFi Drop项目设计主要界面,因为项目的使用场景很单一,追求简单的交互,我们来添加一个区域,用户可以将文件或文件夹拖动到这个区域,则可以实现对这些文件的发送,另外有的用户还可能喜欢在工具中通过点击一个按钮的方式来打开文件管理器,选择想要发送的文件,因此我们在增加一个按钮。接下来我们将使用两种方式添加这两个控件。
在添加之前我们要考虑我们希望怎么布局这两个按钮 。

我们希望像上图一样,左边是一个按钮,而右边是一个可以拖动文件进去的区域,那么我们希望这两个控件横向排列,为了保证控件之间的位置精准的对其,而不会由于人拜访的时候带来的不协调,Qt提供了Layout的概念,Layout就像是给界面上画了格子,而控件就是摆放在这些格子中的物件,在左侧Layout界面中我们依次来拖动两个Layout出来,一个是纵向一个是横向的Layout,两个Layout拖动出来并没有什么外观上的差别,但是在使用的时候,纵向Layout紧允许我们纵向排列控件,而横向Layout则只允许我们横向排列控件我们要做类似这样的排列结构,图中蓝色会纵向Layout,橙色为横向Layout,我们绿色两个为控件,我们希望按钮居中,因此在按钮上下我们放置两个纵向空间调节控件(Vertical Spacer),从而组成一个整体,这个整体跟文件拖放区域控件横向排列。我们使用Label(标签控件)来实现文件拖放区域。

在Qt Creator中将控件拖入到Layout中实现添加。我们将使用两种不同的方法添加这两个控件,在Qt Creator中使用绘制的方式添加按钮,而通过编程代码的形式添加Label控件作为文件拖放区域。
当控件添加完毕以后,我们就可以在右侧的对象窗口中选中想要修改的控件,同时使用下边的属性编辑器来修改其初始化属性,比如我们希望修改按钮的对象名称,以及上边显示的文字,则可以修改下边三项
- 将主窗口控件的windowTitle改为我们的程序名“WiFi Drop”
- 将objectName改为pushButtonChoose,以后在代码中通过这个名称来操作这个控件
- 通过修改text属性来修改按钮上的文字
还有很多其他的属性,可以参考,Qt官方文档 https://doc.qt.io/qt-5/qpushbutton.html ,因为这个类是继承自 [QAbstractButton][1],因此有必要还需要查阅 [QAbstractButton][1] 的文档以及再上一层的类文档。一个简单的方法是,在Qt Creator的属性修改器中可以浏览全部支持的属性,有些如果需要在程序中动态修改,可以相应的在代码中修改对应的属性的值 。

2. 写点代码,运行起来
2.1 实例化主窗口
到这里我们的主界面就已经设计完成了。接下来我们要开始编写py代码,将这界面展示出来。在项目根目录中新建一个main.py文件。我们有了设计好的ui文件,那么怎么在代码中加载它呢,首先我们要创建一个主窗口的类,这个类继承自Qt提供的QMainWindow,然后在利用PyQt5提供的loadUi函数可以直接将ui文件加载成Python对象,首先在main.py中导入需要用的的类 。
|
|
然后创建我们的主窗口类,并将画好的ui加载进来,另外我们不想要状态栏,通过代码self.ui.setStatusBar(None)在主窗口类初始化的时候隐藏掉状态栏 。
|
|
然后,我们在程序入口,创建Qt应用,并展示主窗口,如果程序退出了,我们希望能捕捉到程序的退出代码 。
|
|
运行代码我们的主窗口就可以展示出来了 :

2.2 利用代码添加拖放区控件
是不是还缺少点什么? 对了,我们的文件拖动区域呢。接下来我们使用代码的方式添加标签控件作为文件拖动区域,因为我们要自定义标准标签控件上拖放文件时的行为,我们需要从QLabel控件继承并创建一个自己的控件。
|
|
我们定义了一个DropArea,而这个类继承自QLabel控件,同时我们在初始化的时候允许该控件接受拖放,然后我们定义了dragEnterEvent,该函数会在我们用鼠标拖动文件到该控件上时被触发,最后,我们定义了dropEvent,该函数会在鼠标拖动到上边以后,放开鼠标左键的时候被触发。而event.mimeData().urls()上则返回一个多个QUrl类型的实体,每一个QUrl中包含了每一个文件的路径,通过toLocalFile()可以获取到QUrl中包含的在当前系统上的全路径格式。
有了自定义的DropArea控件,我们通过程序动态的将该控件添加到横向Layout中。在Qt Creator的对象窗口中我们很容易的找到,横向Layout的对象名为horizontalLayout,然后使用horizontalLayout的addItem方法添加控件进去。
在MainWindow类的初始化函数最后添加如下代码,从而在主界面中添加拖放区
|
|
运行代码我们的主窗口就可以支持拖放了 :
2.2 利用信号槽实现用户点击响应
另外我们还希望用户通过点击选择按钮可以在文件浏览器中选择想要发送的文件,这里我们要引入Qt中一个重要的概念信号槽,即signal和slot,所谓信号就是一个事件,可以是用户操作,也可以是我们在程序中设定的,而槽就是当事件触发以后我们想要执行的函数。如果你有过GUI编程经验的话,其实都是类似的,用户和界面交互的时候(点击一个按钮,输入一些文字等等)这些都是事件,而我们期望界面对这些事件进行一些响应动作,则需要触发一些函数的调用。所谓信号槽就是用来完成这件事情的。
在这里,按钮被点击就是事件,也就是信号,在信号触发之后,我们希望调用一个自定义函数打开文件选择窗口,那么这个自定义函数就是我们要定义的槽,然后将信号和槽进行连接,就实现了联动。在MainWindow的初始化中,将主界面上的按钮的点击信号通过connect方法连接到我们自定义的类方法pushButtonChoose_clicked,也就是槽 。
|
|
在该类方法中,打开一个文件对话框,并返回用户选择的文件名。
|
|
另外我们在用户选择文件之后,以及拖放文件之后,将文件名打印到了终端。
3. 本章完结效果
本章节最终实现的源代码可以在git仓库 https://github.com/pythonlibrary/wifidrop 中的** tutorial-2 **tag的commit位置找到 。
最终实现的效果为:
系列文章传送门:
类似文章

PyQt5教程1:项目介绍和环境搭建
编程从来都是一门实践性很强的技术,最好的学习方式就是动起手来 写在前面 关于如何使用PyQt(PyQt4或者PyQt5)在网上有很多简单或者详细的教程,但是我发现大部分的教程是从一个最简单的点展开,试图从一个Hello World讲起,手动创建控件,比如如何用代码创建一个按钮,如果在按钮上绑定一个事件,如何利用该事件输出文字到文字框等等。还有一些教程,非常详尽的讲解每一个控件具有哪些功能,并展示如何使用。前者更像是一本教材,准备由浅入深,但是很多人可能在Hello World之后就因为枯燥的示例被劝退,后者更像一本参考资料,很少希望从头到尾的学习完所有控件。
阅读更多
Linux内核开发之编译和运行
在本篇文章中,读者可以跟着我们的一步一步的教程最终学会如何搭建Linux内核开发环境,并最终能成功运行自己编译的内核,本文主要是针对arm架构来编译Linux内核,因此读者不仅可以学习到如果编译内核,还将学会如何使用QEMU搭建arm仿真环境。 本文将介绍两种Linux内核编译方法 第一种为不借助任何编译系统的原始编译方法,相对较为复杂 第二种则借助BuildRoot编译系统实现了一键编译,相对比较简单 编译Linux内核需要在Linux系统中运行,推荐使用Ubuntu,并安装 build-essentials 包,本
阅读更多
智能家居好伙伴 树莓派,MQTT和Python – 下篇
在本篇文章中,我们主要结合代码来讲解,如何在树莓派上使用Python开发基于MQTT的通讯机制, 项目的整体设计请阅读智能家居好伙伴 树莓派,MQTT和Python – 上篇 本文中提到的代码均在GitHub上共享,大家可以在文章结尾找到GitHub仓库地址。
阅读更多