目录

一、绝对布局

二、盒布局

三、格栅布局

四、格栅布局跨行跨列显示

布局管理即设置窗体上各个控件的位置,对于新手来说,这是学习的难点。

布局管理根据绝对坐标是否变动分为绝对布局和相对布局两大类。采用相对布局的窗口在变大或缩小时,各控件的位置关系会保持固定比例做相应变动。而采用绝对布局的窗口变动时,空间位置不会变动。

而相对布局根据方式不同,又可以分为水平布局(QHBoxLayout)、垂直布局管理(QVBoxLayout)、栅格布局管理(QGridLayout)、表单布局管理(QFormLayout)。

一、绝对布局

绝对布局中以像素为单位区分元素的位置,衡量元素的大小,以设定坐标的方式精准的定位每个控件的位置,但是这种布局方式也有缺点:

  • 窗体控件无法根据窗口的位置和大小而变化;
  • 改变字体大小时可能会破坏布局;
  • 当分辨率有较大改变时,原有布局会破坏;
  • 在设计阶段,如果需要添加或删除控件,如果要调整控件位置,就需要全部调整。

下面是绝对布局的示例:

  1. import sys,os
  2. from PyQt5.QtWidgets import QWidget,QLabel,QApplication
  3. from PyQt5.QtGui import QIcon
  4.  
  5. path = os.path.dirname(os.path.dirname( os.path.dirname(__file__)))
  6.  
  7. class MyWindow(QWidget):
  8.  
  9. def __init__(self):
  10. super(MyWindow, self).__init__()
  11. self.initUI()
  12.  
  13. def initUI(self):
  14. self.setGeometry(300,300,500,400)
  15. self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path))
  16. self.setWindowTitle('绝对布局示例')
  17.  
  18. lbl1 = QLabel('这是第一个标签',self)
  19. lbl1.setGeometry(80,80,30,30)
  20.  
  21. lbl2 = QLabel('这是第二个标签',self)
  22. lbl2.move(150,150)
  23.  
  24. if __name__ == '__main__':
  25. app = QApplication(sys.argv)
  26. win = MyWindow()
  27. win.show()
  28. sys.exit(app.exec_())

绝对布局示例

效果图如下:

根据效果图可以发现:

  1. 在改变窗口长和宽的时候,两个标签的位置不会变动;
  2. 两个标签用不同的方法创建。第一个标签不仅设定了位置,还固定了大小,所以内容不能完全展示。

二、盒布局(Box Layout)

采用盒布局的窗口在改变窗体大小时,各控件会按相应比例自动调整。代码如下:

  1. import sys,os
  2. from PyQt5.QtWidgets import QApplication,QHBoxLayout,QVBoxLayout,QWidget,QPushButton
  3. from PyQt5.QtGui import QIcon
  4.  
  5. path = os.path.dirname(os.path.dirname( os.path.dirname(__file__)))
  6.  
  7. class MyWindow(QWidget):
  8.  
  9. def __init__(self):
  10. super(MyWindow, self).__init__()
  11. self.initUI()
  12.  
  13. def initUI(self):
  14. self.setGeometry(300,300,500,400)
  15. self.setWindowIcon(QIcon(r'%s/4.图标素材/chuan.ico' % path))
  16. self.setWindowTitle('盒布局示例')
  17.  
  18. okbutton = QPushButton('确认') #设置“确认”按钮
  19. cancelbutton = QPushButton('取消') #设置“取消”按钮
  20.  
  21. hbox = QHBoxLayout() #布局实例化对象
  22. hbox.addStretch(1) #设置分配比例
  23. hbox.addWidget(okbutton) #添加“确认”按钮到窗体
  24. hbox.addWidget(cancelbutton)
  25.  
  26. vbox = QVBoxLayout()
  27. vbox.addStretch(1)
  28. vbox.addLayout(hbox)
  29.  
  30. self.setLayout(vbox) #设置窗体布局
  31.  
  32. if __name__ == '__main__':
  33. app = QApplication(sys.argv)
  34. win = MyWindow()
  35. win.show()
  36. sys.exit(app.exec_())

盒布局示例

盒布局中使用stretch函数在布局中增加了一个伸缩量,里面的参数表示QSpacerItem的个数,默认值为零(也可以理解为除去控件外,空白部分所占的比例),会将你放在layout中的空间压缩成默认的大小。而且在窗体缩小时,这个伸缩量也可以变小,直至为零。

“确认”和“取消”两个按钮出现在窗体右下角。示例中实现的方法是首先创建一个垂直布局,按钮上部伸缩量占比为1,接着把这整个布局放在水平布局里,伸缩量占比为1.于是实现了给出的显示效果。

下面对addstretch方法做个补充讲解:

  1. import sys,os
  2. from PyQt5.QtWidgets import QApplication,QHBoxLayout,QVBoxLayout,QWidget,QPushButton
  3. from PyQt5.QtGui import QIcon
  4.  
  5. path = os.path.dirname(os.path.dirname( os.path.dirname(__file__)))
  6.  
  7. class MyWindow(QWidget):
  8.  
  9. def __init__(self):
  10. super(MyWindow, self).__init__()
  11. self.initUI()
  12.  
  13. def initUI(self):
  14. self.setGeometry(300,300,500,300)
  15. self.setWindowIcon(QIcon(r'%s/4.图标素材/chuan.ico' % path))
  16. self.setWindowTitle('addstrtch示例')
  17.  
  18. fir_button = QPushButton('按钮一') #设置按钮一
  19. sec_button = QPushButton('按钮二') #设置按钮二
  20. thir_button = QPushButton('按钮三') #设置按钮三
  21.  
  22. hbox = QHBoxLayout()
  23. hbox.addStretch(1)
  24. hbox.addWidget(fir_button)
  25. hbox.addStretch(2)
  26. hbox.addWidget(sec_button)
  27. hbox.addStretch(3)
  28. hbox.addWidget(thir_button)
  29.  
  30. # vbox = QVBoxLayout()
  31. # vbox.addStretch(1)
  32. # vbox.addLayout(hbox)
  33.  
  34. self.setLayout(hbox) #设置窗体布局
  35.  
  36. if __name__ == '__main__':
  37. app = QApplication(sys.argv)
  38. win = MyWindow()
  39. win.show()
  40. sys.exit(app.exec_())

addstretch方法示例

使用addstretch方法分别给定了参数1、2、3,即在水平布局上,除去按钮部分外的空白区域,按照1:2:3的比例分配空间。下过如下图所示。

三、格栅布局

格栅布局是最常用的布局方式,下面我们通过模拟计算器界面的方式来学习格栅布局。

  1. import sys,os
  2. from PyQt5.QtWidgets import QApplication,QPushButton,QWidget,QGridLayout
  3. from PyQt5.QtGui import QIcon
  4.  
  5. path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
  6.  
  7. class MyWindow(QWidget):
  8.  
  9. def __init__(self):
  10. super(MyWindow, self).__init__()
  11. self.initUI()
  12.  
  13. def initUI(self):
  14. self.setWindowTitle('格栅布局示例')
  15. self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path))
  16. self.setGeometry(600,300,500,400)
  17.  
  18. names = ['On','Off','AC','/',
  19. '','','','*',
  20. '','','','-',
  21. '','','','+',
  22. '','','.','=']
  23.  
  24. positions = [(i,j) for i in range(5) for j in range(4)]
  25.  
  26. grid = QGridLayout()
  27. self.setLayout(grid)
  28. for position,name in zip(positions,names):
  29. button = QPushButton(name)
  30. grid.addWidget(button,*position)
  31.  
  32. if __name__ == '__main__':
  33. app = QApplication(sys.argv)
  34. win = MyWindow()
  35. win.show()
  36. sys.exit(app.exec_())

格栅布局示例

显示效果如下:

下面来分析代码

  1. names = ['On','Off','AC','/',
  2. '7','8','9','*',
  3. '4','5','6','-',
  4. '1','2','3','+',
  5. '0','00','.','=']

names列表是各按键的名称。

  1. positions = [(i,j) for i in range(5) for j in range(4)]

 这个列表生成式生成的列表类似一个矩阵,各元素的数值恰好是按钮在格栅布局中位置

  1. for position,name in zip(positions,names):
  2. button = QPushButton(name)
  3. grid.addWidget(button,*position)

 这里使用的zip函数。python3中为了减少内存,zip函数返回的是一个对象。如果要展示列表,可通过 list() 转换。

  1. names = ['On','Off','AC','/',
  2. '7','8','9','*',
  3. '4','5','6','-',
  4. '1','2','3','+',
  5. '0','00','.','=']
  6. positions = [(i,j) for i in range(5) for j in range(4)]
  7. a = zip(names,positions)
  8.  
  9. print(a)
  10. print(list(a))
  11.  
  12. 显示效果如下:
  13. <zip object at 0x0000020EFF489508>
  14. [('On', (0, 0)), ('Off', (0, 1)), ('AC', (0, 2)), ('/', (0, 3)), ('7', (1, 0)), ('8', (1, 1)), ('9', (1, 2)), ('*', (1, 3)), ('4', (2, 0)), ('5', (2, 1)), ('6', (2, 2)), ('-', (2, 3)), ('1', (3, 0)), ('2', (3, 1)), ('3', (3, 2)), ('+', (3, 3)), ('0', (4, 0)), ('00', (4, 1)), ('.', (4, 2)), ('=', (4, 3))]

 四、格栅布局跨行跨列显示

虽然格栅布局最常用,但是实际窗口的控件往往是大小不一的,单个控件跨行跨列很常见,下面来介绍下跨行跨列的情况。

  1. import sys,os
  2. from PyQt5.QtWidgets import QWidget,QPushButton,QLabel,QLineEdit,QApplication,QGridLayout
  3. from PyQt5.QtGui import QIcon, QPixmap
  4.  
  5. path = os.path.dirname(os.path.dirname(os.path.dirname(__file__)))
  6.  
  7. class MyWindow(QWidget):
  8.  
  9. def __init__(self):
  10. super().__init__()
  11. self.initUI()
  12.  
  13. def initUI(self):
  14. self.setWindowTitle('跨行跨列布局示例')
  15. self.setWindowIcon(QIcon(r'%s\4.图标素材\chuan.ico' % path))
  16. self.setGeometry(600,300,450,300)
  17.  
  18. lbl_image = QLabel()
  19. png = QPixmap(r'%s\4.图标素材\cartoon1.ico' % path)
  20. lbl_image.setPixmap(png)
  21. lbl_image.setScaledContents(True) #图片自适应标签大小
  22.  
  23. lbl_user = QLabel('账号:') #设置标签
  24. lbl_pwd = QLabel('密码:')
  25. okbutton = QPushButton('确认') #设置按钮
  26. cancelbutton = QPushButton('取消')
  27. lineedit_user = QLineEdit() #设置单行文本框
  28. lineedit_pwd = QLineEdit()
  29.  
  30. grid = QGridLayout()
  31. self.setLayout(grid)
  32. grid.setSpacing(10) #间距为10
  33.  
  34. grid.addWidget(lbl_image,1,1,3,1)
  35. grid.addWidget(lineedit_user,1,2,1,2)
  36. grid.addWidget(lineedit_pwd,2,2,1,2)
  37. grid.addWidget(lbl_user,1,4)
  38. grid.addWidget(lbl_pwd,2,4)
  39. grid.addWidget(okbutton,3,2,1,1)
  40. grid.addWidget(cancelbutton,3,3,1,1)
  41.  
  42. if __name__ == '__main__':
  43. app = QApplication(sys.argv)
  44. win = MyWindow()
  45. win.show()
  46. sys.exit(app.exec_())

跨行跨列示例

显示效果如下:

下面来分析代码:

  1. grid.addWidget(lbl_image,1,1,3,1)

 addwidget方法第一个参数是添加的控件对象,后面的(1,1)表示位置坐标为(1,1),即控件左上角坐标为(1,1)。这里的1并不是以像素为单位,而是以行和列为单位,(1,1)即第一行第一列。最后的(3,1)意思是这个控件占三行1列。下面用表格和图片来表示布局方式

图片

(3行1列)

单行文本框1 “账号”标签
单行文本框2 “密码”标签
“确认”按钮 “取消”按钮  
  1. grid.setSpacing(10)

 即各控件之间的上下间距为10(以像素为单位)。同理还有grid.setMargin(int)为设置控件之间的左右间距。


四、PyQt5布局管理(绝对&相对、水平、垂直、格栅、表单)的更多相关文章

  1. PyQt5布局管理器

    布局分类 绝对定位:使用move方法将空间直接定死在某个坐标,不会随着窗口大小的改变而改变 可变布局:使用各种布局管理器,实现组件的位置和大小随着窗口的变化而变化 布局管理器 QHBoxLayout: ...

  2. PyQt5——布局管理

    PyQt5布局管理使用方法详见:https://blog.csdn.net/jia666666/article/list/3?t=1& PyQt5布局管理汇总: 1.QHBoxLayout 2 ...

  3. PyQt5布局管理(1)

    Qt布局管理按简单分可分为绝对位置布局和布局管理器布局 一.绝对位置布局: 组件不放在布局管理器中,通过函数setGeometry(x,y,width,height)来设定组件相对其父窗口的位置.其中 ...

  4. Bootstrap3 表单-水平排列的表单

    通过为表单添加 .form-horizontal 类,并联合使用 Bootstrap 预置的栅格类,可以将 label 标签和控件组水平并排布局.这样做将改变 .form-group 的行为,使其表现 ...

  5. python 全栈开发,Day111(客户管理之 编辑权限(二),Django表单集合Formset,ORM之limit_choices_to,构造家族结构)

    昨日内容回顾 1. 权限系统的流程? 2. 权限的表有几个? 3. 技术点 中间件 session orm - 去重 - 去空 inclusion_tag filter 有序字典 settings配置 ...

  6. angularjs学习第四天笔记(第一篇:简单的表单验证)

    您好,我是一名后端开发工程师,由于工作需要,现在系统的从0开始学习前端js框架之angular,每天把学习的一些心得分享出来,如果有什么说的不对的地方,请多多指正,多多包涵我这个前端菜鸟,欢迎大家的点 ...

  7. Servlet会话管理一(URL重写和表单隐藏域)

    会话可以简单的理解为客户端用户打开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器的整个过程称为一个会话.即一个客户端用户和服务器端进行通讯的过程,也是客户端和服务器端之间的数据传 ...

  8. HTML5 01. 布局、语义化标签、智能化表单、表单元素/标签/属性/事件、多媒体、类操作、自定义属性

    1.知识点 lang = “en”   所用语言是英文 文档结构更简洁 IE8一下不支持h5c3 书写更宽松 div没有语义 标签语义化:在合适的地方使用合适的标签 对seo优化友谊 网页经典布局 页 ...

  9. pyqt5 -—-布局管理

    绝对布局 例如: 我们使用move()方法定位了每一个元素,使用x.y坐标.x.y坐标的原点是程序的左上角. lbl1 = QLabel('Zetcode', self) lbl1.move(15, ...

随机推荐

  1. nginx配置多个域名

    1.原来的80端口改掉,下面配置: server { listen 80; server_name *.pobohn.com; location / { proxy_pass http://local ...

  2. python爬虫相关

    一.Python re模块的基本用法: https://blog.csdn.net/chenmozhe22/article/details/80601971 二.爬取网页图片 https://www. ...

  3. 系统设计与架构笔记:ETL工具开发和设计的建议

    最近项目组里想做一个ETL数据抽取工具,这是一个研发项目,但是感觉公司并不是特别重视,不重视不是代表它不重要,而是可能不会对这个项目要求太高,能满足我们公司的小需求就行,想从这个项目里衍生出更多的东西 ...

  4. URL 传递问题

    工作日记: ----更正:如下做改成%26是不行的.正在寻求解决方法 在K2邮件发送正文中我拼接了URL如:http://shisupportqa:8090/WorkflowPages/SendFil ...

  5. java8 for ,forEach ,lambda forEach , strean forEach , parller stream forEach, Iterator性能对比

    java8 for ,forEach ,Iterator,lambda forEach ,lambda  strean forEach , lambda parller stream forEach性 ...

  6. assert (boxes[:, 2] >= boxes[:, 0]).all()报错

    根据报错信息,打印以下内容: 代码如下: for i in xrange(num_images): #print ('in append_flipped==================',self ...

  7. QT项目添加现有文件后不能运行,MFC在类视图中自动隐藏类

    解决方案:1)QT 5.6版本的QtCreator打开pro文件,在最后加一行空行或者删除一行空行,保存即可: 2)在隐藏的类对应的头文件中增加一行或删除一行(空格也可以),即可自动出现.

  8. Linux 下安装 apache

    1.检查是否已经安装过 apache (linux 中 apache 的名字是 httpd) rpm -qa  httpd 2.如果没有安装过,运行如下命令 yum install httpd -y ...

  9. dubbo 概述和使用

    dubbo核心概念 apache是一款高性能.轻量级的开源java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现 官网:http://dubbo ...

  10. SpringMVC中注解@RequestBody和@ResponseBody的使用区别

    首先上源码 在面试时经常会问到我们如何使用SpringMVC将Http请求转换为java对象,或者又是问如何将结果转换为java的呢? SpringMVC在接收到请求之后HandlerMapping像 ...