PyQt5的相对布局管理的实现


Posted in Python onAugust 07, 2020

博主PyQt5新手,最近在写一个可视化展示界面,第一个遇到的坑就是布局管理。

其实可以不用相对布局,直接用QtDesigner进行傻瓜式的拖控件也不是不可以,高级一点,也可以用绝对布局,定义控件的绝对位置,就可以避免踏入这个坑了。

但是,还是建议大家,尤其是新手使用相对布局,一个感受,就是相对布局美观整齐,控件不会乱。

写在前面

如果大家完全初学,建议大家买本书看看,我发现网上能搜到的关于PyQt5教程都是从书上来的,而且网上的教程都是书本的搬运工,少有自己的思考,比如如何活用布局,也就是这篇博文要解决的内容。建议大家看看《PyQt5快速开发与实战这本书》,总体不错,博主的很多解决方案都是从这本书上来。
下面是编译环境:

  • python3.7,编译器是pycharm,特别说明,不要用Spyder,如果只是常规的控件用Spyder没啥问题,但是如果你用了QWebEngineView,会让你崩溃到怀疑人生,遇到的问题无法解决,一度想要从入门到放弃。博主也是从matlab过来的,大爱Spyder的编译风格,但是建议还是趁早换了,pycharm的代码自动填充功能不要太爽;
  • 要实现的功能:设置两排横向的按钮,一个网页展示区,和网页并排展示的文本框用来展示数据,展示效果如下:

PyQt5的相对布局管理的实现

用到的包

常规包导入

from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import Qt, QUrl
import sys

QWebEngineView是用来展示百度首页的,用Spyder编译的话,一直会报错,报错如下:
QtWebEngineWidgets must be imported before a QCoreApplication instance is created

界面生成

编写初始化函数,代码如下:

class MyWindow(QWidget): 

	def __init__(self): 
		super(MyWindow,self).__init__()
		self.setWindowTitle('嵌套布局示例')
		self.resize(1000, 800)
		self.browser = QWebEngineView(self) #1
		self.textEdit = QTextEdit(self) #2
		self.browser_init() #3
		self.layout_init() #4
#1 定义一个浏览器控件
#2 定义一个文本编辑框,个人用于展示网页显示的数据
#3 初始化浏览器设置
#4 布局设置

布局设置

不说废话,直接上代码

def layout_init(self):

    # 全局部件(注意参数 self),用于"承载"全局布局
		wwg = QWidget(self)


    
     # 全局布局(注意参数 wwg)
		wl = QVBoxLayout(wwg) 
		hlayout1 = QHBoxLayout()
		hlayout2 = QHBoxLayout()
		hlayout3 = QHBoxLayout()
		#vlayout = QVBoxLayout()
		#glayout = QGridLayout()
		#formlayout = QFormLayout()
    
     # 局部布局添加部件(例如:按钮)
		hlayout1.setSpacing(0)
		#hlayout1.addStretch(1)
		hlayout1.addWidget( QPushButton(str(1)) )
		#hlayout1.addStretch(1)
		hlayout1.addWidget( QPushButton(str(2)) )
		#hlayout1.addStretch(1)
		hlayout1.addWidget( QPushButton(str(3)) )
		#hlayout1.addStretch(1)
		hlayout1.addWidget( QPushButton(str(4)) )
		#hlayout1.addStretch(1)

		hlayout2.addStretch(1)
		hlayout2.addWidget( QPushButton(str(1)) )
		hlayout2.addStretch(1)
		hlayout2.addWidget( QPushButton(str(2)) )
		hlayout2.addStretch(1)
		hlayout2.addWidget( QPushButton(str(3)) )
		hlayout2.addStretch(1)
		hlayout2.addWidget( QPushButton(str(4)) )
		hlayout2.addStretch(1)

		#hlayout3.addStretch(1)
		hlayout3.setSpacing(0)
		hlayout3.addWidget(self.browser)
		#hlayout3.addStretch(1)
		hlayout3.addWidget(self.textEdit)
		#hlayout3.addStretch(1)

		#self.setLayout(hlayout)
		#vlayout.addWidget( QPushButton(str(3)) )
		#vlayout.addWidget( QPushButton(str(4)) )
		#glayout.addWidget( QPushButton(str(5)) , 0, 0 )
		#glayout.addWidget( QPushButton(str(6)) , 0, 1 )
		#glayout.addWidget( QPushButton(str(7)) , 1, 0)
		#glayout.addWidget( QPushButton(str(8)) , 1, 1)
		#formlayout.addWidget( QPushButton(str(9)) )
		#formlayout.addWidget( QPushButton(str(10)) )
		#formlayout.addWidget( QPushButton(str(11)) )
		#formlayout.addWidget( QPushButton(str(12)) )
    
    # 这里向局部布局内添加部件,将他加到全局布局
		wl.addLayout(hlayout1)
		wl.addLayout(hlayout2)
		wl.addLayout(hlayout3)
		#wl.addLayout(vlayout)
		#wl.addLayout(glayout)
		#wl.addLayout(formlayout)

		self.setLayout(wl)

下面对重要代码进行逐行解释:

#wwg = QWidget(self)这里定义了一个全局的布局,接下来,所有的布局都会放在这个布局里进行设置

#wl = QVBoxLayout(wwg)这里将wwg这个全局布局设置为整体的垂直布局,接下来所有的布局都是用的垂直布局

hlayout1 = QHBoxLayout()
		hlayout2 = QHBoxLayout()
		hlayout3 = QHBoxLayout()

这里设置三个水平布局,第一个水平布局的控件设置的是按钮,第二个也是按钮,第三个左边是网页,右边是文本编辑框。这三个水平布局按照整体垂直布局从上往下摆放。

下面依次给这三个水平布局添加控件:

第一个水平控件用了setSpacing(0)来设置按钮间距,可以保证按钮从左到右无间距的布满整个横排;

第二个水平控件用了addStretch(1)按比例来分配设置控件后的剩余控件,大家可以看最前面的两排按钮的区别;

第三个水平控件因为想要来放置网页和文本框,所以尽量要布满界面,所以用的是setSpacing(0)进行间距设置。

接下来就是将这三个水平布局添加到整体的垂直布局中去了,用如下的方式:

wl.addLayout(hlayout1)
wl.addLayout(hlayout2)
wl.addLayout(hlayout3)

self.setLayout(wl)这句代码很关键,书上没有,它的作用是将窗口本身设置为全局布局,如果不写,效果如下:

PyQt5的相对布局管理的实现

browser设置默认展示百度首页

我写了个函数,当然也可以直接写在__init__(self)中,不过为了便于理解,建议大家还是写函数

def browser_init(self):
		self.browser.load(QUrl('https://baidu.com'))

结果展示

是不是以为已经写完了,图样图森破,看看展示成什么鬼样子了

PyQt5的相对布局管理的实现

这是什么鬼,为啥左边百度首页展示就这么窄一点点区域,完全不是想要的样子好吗。。。
于是博主一番网上搜索操作,在__init__(self)初始化函数中添加了这么一句代码:

self.textEdit.setFixedWidth(200)

这句代码的作用是将右侧的文本框设置宽度为200,这样就可以了,展示效果就是最上面那张图,如此简单啊。。
学会布局后,就可以随心所欲的添加自己想要的控件了,也完全不用担心美工UI设计出来的花里胡哨的东西了。
当然,博主的开发工作要比这个界面复杂得多,遇到的坑远不止这个布局设置,待相关开发完成后,再一一介绍。

完整代码

最后照旧上完整代码

# -*- coding: utf-8 -*-
"""
Created on Wed Apr 10 08:52:37 2020

@author: HG
"""

from PyQt5.QtWidgets import *
from PyQt5.QtWebEngineWidgets import QWebEngineView
from PyQt5.QtCore import Qt, QUrl
import sys  
 
class MyWindow(QWidget): 

	def __init__(self): 
		super(MyWindow,self).__init__()
		self.setWindowTitle('嵌套布局示例')
		self.resize(1000, 800)
		self.browser = QWebEngineView(self)
		self.textEdit = QTextEdit(self)
		self.browser_init()
		self.layout_init()
		self.textEdit.setFixedWidth(200)



	def layout_init(self):

    # 全局部件(注意参数 self),用于"承载"全局布局
		wwg = QWidget(self)


    
     # 全局布局(注意参数 wwg)
		wl = QVBoxLayout(wwg)
		hlayout1 = QHBoxLayout()
		hlayout2 = QHBoxLayout()
		hlayout3 = QHBoxLayout()
		#vlayout = QVBoxLayout()
		#glayout = QGridLayout()
		#formlayout = QFormLayout()
    
     # 局部布局添加部件(例如:按钮)
		hlayout1.setSpacing(0)
		#hlayout1.addStretch(1)
		hlayout1.addWidget( QPushButton(str(1)) )
		#hlayout1.addStretch(1)
		hlayout1.addWidget( QPushButton(str(2)) )
		#hlayout1.addStretch(1)
		hlayout1.addWidget( QPushButton(str(3)) )
		#hlayout1.addStretch(1)
		hlayout1.addWidget( QPushButton(str(4)) )
		#hlayout1.addStretch(1)

		hlayout2.addStretch(1)
		hlayout2.addWidget( QPushButton(str(1)) )
		hlayout2.addStretch(1)
		hlayout2.addWidget( QPushButton(str(2)) )
		hlayout2.addStretch(1)
		hlayout2.addWidget( QPushButton(str(3)) )
		hlayout2.addStretch(1)
		hlayout2.addWidget( QPushButton(str(4)) )
		hlayout2.addStretch(1)

		#hlayout3.addStretch(1)
		hlayout3.setSpacing(0)
		hlayout3.addWidget(self.browser)
		#hlayout3.addStretch(1)
		hlayout3.addWidget(self.textEdit)
		#hlayout3.addStretch(1)

		#self.setLayout(hlayout)
		#vlayout.addWidget( QPushButton(str(3)) )
		#vlayout.addWidget( QPushButton(str(4)) )
		#glayout.addWidget( QPushButton(str(5)) , 0, 0 )
		#glayout.addWidget( QPushButton(str(6)) , 0, 1 )
		#glayout.addWidget( QPushButton(str(7)) , 1, 0)
		#glayout.addWidget( QPushButton(str(8)) , 1, 1)
		#formlayout.addWidget( QPushButton(str(9)) )
		#formlayout.addWidget( QPushButton(str(10)) )
		#formlayout.addWidget( QPushButton(str(11)) )
		#formlayout.addWidget( QPushButton(str(12)) )
    
    # 这里向局部布局内添加部件,将他加到全局布局
		wl.addLayout(hlayout1)
		wl.addLayout(hlayout2)
		wl.addLayout(hlayout3)
		#wl.addLayout(vlayout)
		#wl.addLayout(glayout)
		#wl.addLayout(formlayout)

		self.setLayout(wl)

	def browser_init(self):
		self.browser.load(QUrl('https://baidu.com'))

if __name__=="__main__":  
 
	app = QApplication(sys.argv)  
	win = MyWindow() 
	win.show() 
	sys.exit(app.exec_())

到此这篇关于PyQt5的相对布局管理的实现的文章就介绍到这了,更多相关PyQt5 相对布局内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
详解Python中列表和元祖的使用方法
Apr 25 Python
django模板语法学习之include示例详解
Dec 17 Python
Django渲染Markdown文章目录的方法示例
Jan 02 Python
Django项目中添加ldap登陆认证功能的实现
Apr 04 Python
python初学者,用python实现基本的学生管理系统(python3)代码实例
Apr 10 Python
python图像和办公文档处理总结
May 28 Python
Python基于BeautifulSoup和requests实现的爬虫功能示例
Aug 02 Python
使用Python实现分别输出每个数组
Dec 06 Python
jupyternotebook 撤销删除的操作方式
Apr 17 Python
Win10环境中如何实现python2和python3并存
Jul 20 Python
基于python调用jenkins-cli实现快速发布
Aug 14 Python
忆童年!用Python实现愤怒的小鸟游戏
Jun 07 Python
详解pyqt5的UI中嵌入matplotlib图形并实时刷新(挖坑和填坑)
Aug 07 #Python
Python configparser模块封装及构造配置文件
Aug 07 #Python
Python logging模块进行封装实现原理解析
Aug 07 #Python
Python定时任务APScheduler安装及使用解析
Aug 07 #Python
Python如何解除一个装饰器
Aug 07 #Python
解决Pycharm双击图标启动不了的问题(JetBrains全家桶通用)
Aug 07 #Python
Python实现上下文管理器的方法
Aug 07 #Python
You might like
PHP闭包(Closure)使用详解
2013/05/02 PHP
php_screw安装使用教程(另一个PHP代码加密实现)
2014/05/29 PHP
使用PHP+AJAX让WordPress动态加载文章的教程
2015/12/11 PHP
PHP严重致命错误处理:php Fatal error: Cannot redeclare class or function
2017/02/05 PHP
php根据用户名和手机号查询是否存在手机号码
2017/02/16 PHP
Yii框架引入coreseek分页功能示例
2019/02/08 PHP
Yii框架Session与Cookie使用方法示例
2019/10/14 PHP
深入认识javascript中的eval函数
2009/11/02 Javascript
微博@符号的用户名提示效果。(想@到谁?)
2010/11/05 Javascript
关于Ext中form移除textfield方法:hide(),setVisible(false),remove()
2010/12/02 Javascript
浅谈jQuery中height与width
2015/07/06 Javascript
详解javascript传统方法实现异步校验
2016/01/22 Javascript
js倒计时显示实例
2016/12/11 Javascript
jquery实现页面加载效果
2017/02/21 Javascript
前端自动化开发之Node.js的环境搭建教程
2017/04/01 Javascript
解决vue-router中的query动态传参问题
2018/03/20 Javascript
微信小程序6位或多位验证码密码输入框功能的实现代码
2018/05/29 Javascript
微信小程序自定义纯净模态框(弹出框)的实例代码
2020/03/09 Javascript
关于JavaScript中异步/等待的用法与理解
2020/11/18 Javascript
[36:17]DOTA2上海特级锦标赛 - VGL音乐会全集
2016/03/06 DOTA
python Django连接MySQL数据库做增删改查
2013/11/07 Python
python读取TXT到数组及列表去重后按原来顺序排序的方法
2015/06/26 Python
Python实现定时自动关闭的tkinter窗口方法
2019/02/16 Python
python扫描线填充算法详解
2020/02/19 Python
如何实现更换Jupyter Notebook内核Python版本
2020/05/18 Python
Python绘制组合图的示例
2020/09/18 Python
CSS3中几个新增加的盒模型属性使用教程
2016/03/01 HTML / CSS
C语言编程练习
2012/04/02 面试题
思想汇报格式
2014/01/05 职场文书
网络管理专业求职信
2014/03/15 职场文书
优秀少先队辅导员先进事迹材料
2014/05/18 职场文书
毕业实习单位意见
2015/06/04 职场文书
欠条范文
2015/07/03 职场文书
MySQL限制查询和数据排序介绍
2022/03/25 MySQL
GoFrame基于性能测试得知grpool使用场景
2022/06/21 Golang
python自动获取微信公众号最新文章的实现代码
2022/07/15 Python