这一篇文章中,我们要实现的是主界面和主界面上需要支持的一些功能,我们将使用Qt Creator来创建我们的基本主界面。
打开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控件作为文件拖放区域。
当控件添加完毕以后,我们就可以在右侧的对象窗口中选中想要修改的控件,同时使用下边的属性编辑器来修改其初始化属性,比如我们希望修改按钮的对象名称,以及上边显示的文字,则可以修改下边三项
还有很多其他的属性,可以参考,Qt官方文档 https://doc.qt.io/qt-5/qpushbutton.html,因为这个类是继承自 [QAbstractButton][1],因此有必要还需要查阅 [QAbstractButton][1] 的文档以及再上一层的类文档。一个简单的方法是,在Qt Creator的属性修改器中可以浏览全部支持的属性,有些如果需要在程序中动态修改,可以相应的在代码中修改对应的属性的值 。
到这里我们的主界面就已经设计完成了。接下来我们要开始编写py代码,将这界面展示出来。在项目根目录中新建一个main.py文件。我们有了设计好的ui文件,那么怎么在代码中加载它呢,首先我们要创建一个主窗口的类,这个类继承自Qt提供的QMainWindow,然后在利用PyQt5提供的loadUi函数可以直接将ui文件加载成Python对象,首先在main.py中导入需要用的的类 。
|
|
然后创建我们的主窗口类,并将画好的ui加载进来,另外我们不想要状态栏,通过代码self.ui.setStatusBar(None)在主窗口类初始化的时候隐藏掉状态栏 。
|
|
然后,我们在程序入口,创建Qt应用,并展示主窗口,如果程序退出了,我们希望能捕捉到程序的退出代码 。
|
|
运行代码我们的主窗口就可以展示出来了 :
是不是还缺少点什么? 对了,我们的文件拖动区域呢。接下来我们使用代码的方式添加标签控件作为文件拖动区域,因为我们要自定义标准标签控件上拖放文件时的行为,我们需要从QLabel控件继承并创建一个自己的控件。
|
|
我们定义了一个DropArea,而这个类继承自QLabel控件,同时我们在初始化的时候允许该控件接受拖放,然后我们定义了dragEnterEvent,该函数会在我们用鼠标拖动文件到该控件上时被触发,最后,我们定义了dropEvent,该函数会在鼠标拖动到上边以后,放开鼠标左键的时候被触发。而event.mimeData().urls()上则返回一个多个QUrl类型的实体,每一个QUrl中包含了每一个文件的路径,通过toLocalFile()可以获取到QUrl中包含的在当前系统上的全路径格式。
有了自定义的DropArea控件,我们通过程序动态的将该控件添加到横向Layout中。在Qt Creator的对象窗口中我们很容易的找到,横向Layout的对象名为horizontalLayout,然后使用horizontalLayout的addItem方法添加控件进去。
在MainWindow类的初始化函数最后添加如下代码,从而在主界面中添加拖放区
|
|
运行代码我们的主窗口就可以支持拖放了 :
另外我们还希望用户通过点击选择按钮可以在文件浏览器中选择想要发送的文件,这里我们要引入Qt中一个重要的概念信号槽,即signal和slot,所谓信号就是一个事件,可以是用户操作,也可以是我们在程序中设定的,而槽就是当事件触发以后我们想要执行的函数。如果你有过GUI编程经验的话,其实都是类似的,用户和界面交互的时候(点击一个按钮,输入一些文字等等)这些都是事件,而我们期望界面对这些事件进行一些响应动作,则需要触发一些函数的调用。所谓信号槽就是用来完成这件事情的。
在这里,按钮被点击就是事件,也就是信号,在信号触发之后,我们希望调用一个自定义函数打开文件选择窗口,那么这个自定义函数就是我们要定义的槽,然后将信号和槽进行连接,就实现了联动。在MainWindow的初始化中,将主界面上的按钮的点击信号通过connect方法连接到我们自定义的类方法pushButtonChoose_clicked,也就是槽 。
|
|
在该类方法中,打开一个文件对话框,并返回用户选择的文件名。
|
|
另外我们在用户选择文件之后,以及拖放文件之后,将文件名打印到了终端。
本章节最终实现的源代码可以在git仓库 https://github.com/pythonlibrary/wifidrop 中的** tutorial-2 **tag的commit位置找到 。
最终实现的效果为:
系列文章传送门:
Python之所以如此流行,在于它有强大的生态,使用各种各种的库可以帮助用户最快速的解决问题。Python酷致力于输出高质量的Python库相关教程及技术性文章,帮助用户更好更快速的解决问题