python qyqt5 tool

Python PyQt5 教程

 

PyQt5教程 :http://code.py40.com/face

 

教程翻译自http://zetcode.com/gui/pyqt5/

 

PyQt5 的 核心API 以及 扩展应用(CSDN 学院收费视频):https://edu.csdn.net/course/play/9870/222942

pyqt5 - 对文本样式进行操作:https://www.cnblogs.com/XJT2018/p/9835262.html
setStyleSheet 用法:https://www.cnblogs.com/aheng123/p/5630761.html
Pyqt5 —— setStyleSheet 用法:https://blog.csdn.net/weixin_42066185/article/details/82225197

颜色代码查询,RGB 查询:http://tool.chinaz.com/tools/selectcolor.aspx
RGB颜色值转换成十六进制颜色码:https://www.sioe.cn/yingyong/yanse-rgb-16/

 

 

【第一节】PyQt5简介:http://code.py40.com/1948.html
【第二节】PyQt5基本功能:http://code.py40.com/1961.html
【第三节】PyQt5布局管理:http://code.py40.com/1995.html
【第四节】PyQt5菜单和工具栏:http://code.py40.com/1984.html
【第五节】PyQt5事件和信号:http://code.py40.com/2004.html

【第六节】PyQt5 对话框:http://code.py40.com/2009.html

【第七节】PyQt5控件:http://code.py40.com/2018.html
【第八节】PyQt5控件(II):http://code.py40.com/2026.html
【第九节】PyQt 拖拽:http://code.py40.com/2035.html
【第十节】PyQt5绘图:http://code.py40.com/2042.html
【第十一节】PyQt5自定义控件:http://code.py40.com/2049.html
【第十二节】PyQt5俄罗斯方块:http://code.py40.com/2052.html

 

 

PyQt5 说明

 

pyqt5是一套Python绑定Digia QT5应用的框架。它可用于Python 2和3。本教程使用Python 3。Qt库是最强大的GUI库之一。pyqt5的官方网站http://www.riverbankcomputing.co.uk/news

pyqt5 做为 Python 的一个模块,它有 620 多个类和 6000 个函数和方法。这是一个跨平台的工具包,它可以运行在所有主要的操作系统,包括 UNIX,Windows,Mac OS。pyqt5 是双重许可。开发者可以在 GPL 和 商业许可 之间进行选择。

 

pyqt5 的类别分为几个模块,包括以下:

  • QtCore
  • QtGui
  • QtWidgets
  • QtMultimedia
  • QtBluetooth
  • QtNetwork
  • QtPositioning
  • Enginio
  • QtWebSockets
  • QtWebKit
  • QtWebKitWidgets
  • QtXml
  • QtSvg
  • QtSql
  • QtTest

说明:

QtCore包含了核心的非 GUI 功能。
此模块用于处理时间、文件和目录、各种数据类型、流、URL、MIME类型、线程或进程。
QtGui包含类窗口系统集成、事件处理、二维图形、基本成像、字体和文本。
QtWidgets模块包含创造经典桌面风格的用户界面提供了一套UI元素的类。
QtMultimedia包含的类来处理多媒体内容和 API 来访问相机和收音机的功能。
QtBluetooth模块包含类的扫描设备和连接并与他们互动。描述模块包含了网络编程的类。
这些类便于 TCP 和 IP 和 UDP 客户端和服务器的编码,使网络编程更容易和更便携。
QtNetwork网络模块
QtPositioning包含类的利用各种可能的来源,确定位置,包括卫星、Wi-Fi、或一个文本文件。
Enginio模块实现了客户端库访问 Qt 云服务托管的应用程序运行时。
QtWebSockets模块包含实现 WebSocket 协议类。
QtWebKit包含一个基于 Webkit2 图书馆 Web 浏览器 实现类。
QtWebKitWidgets包含的类的基础 webkit1 ,用于 qtwidgets 应用 Web 浏览器的实现。
QtXml包含与 XML 文件的类。这个模块为 SAX 和 DOM API 提供了实现。
QtSvg模块提供了显示 SVG 文件内容的类。可伸缩矢量图形(SVG)是一种描述二维图形和图形应用的语言。
QtSql模块提供操作数据库的类。
QtTest包含的功能,使 pyqt5 应用程序的单元测试

pyqt5 不向后兼容 pyqt4。pyqt5 有几个显著的变化。将旧代码调整到新库并不困难。有几个大的改变如下:

  • Python模块已经重组。一些模块已经删除(qtscript),有的被分割成子模块(QtGui,QtWebKit)。
  • 新的模块作了详细的介绍,包括qtbluetooth,qtpositioning,或enginio。
  • pyqt5只支持新型的信号和槽handlig。电话signal()或slot()不再支持。
  • pyqt5不支持Qt的API被标记为过时或陈旧的任何部分在QT V5.0。

 

 

【第 1 节】 到 【第 4 节】演示代码

 

可以 把 __init__ 函数中的 注释逐个取消,然后运行程序看执行效果 ):


     
     
  1. # -*- coding: utf-8 -*-
  2. # @Author :
  3. # @File : main.py
  4. # @Software: PyCharm
  5. # @description : XXX
  6. import sys
  7. # QMainWindow 类提供了一个主要的应用程序窗口。
  8. # 你用它可以让应用程序添加状态栏,工具栏和菜单栏。
  9. from PyQt5.QtWidgets import QWidget, QMainWindow
  10. from PyQt5.QtWidgets import QApplication
  11. from PyQt5.QtWidgets import QDesktopWidget, QMessageBox, QLabel, QPushButton, QAction
  12. from PyQt5.QtWidgets import QAction, qApp
  13. from PyQt5.QtWidgets import QLineEdit, QTextEdit
  14. from PyQt5.QtWidgets import QHBoxLayout # horizontal 水平布局
  15. from PyQt5.QtWidgets import QVBoxLayout # vertical 垂直布局
  16. from PyQt5.QtWidgets import QGridLayout # Grid 网格布局
  17. from PyQt5.QtGui import QIcon
  18. # 如果不想一个一个 导入,可以 import *
  19. # from PyQt5.QtWidgets import *
  20. class MyForm1(QWidget):
  21. def __init__(self):
  22. super(MyForm1, self).__init__()
  23. # self._init_ui_1()
  24. # self._init_ui_2()
  25. # self._init_ui_3()
  26. # self._init_ui_4()
  27. self._init_ui_5()
  28. pass
  29. def center(self):
  30. """
  31. 控制窗口显示在屏幕中心的方法
  32. :return:
  33. """
  34. # 获得窗口
  35. qr = self.frameGeometry()
  36. # 获得屏幕中心点
  37. cp = QDesktopWidget().availableGeometry().center()
  38. # 显示到屏幕中心
  39. qr.moveCenter(cp)
  40. self.move(qr.topLeft())
  41. def _init_ui_1(self):
  42. """
  43. 重置大小,中心显示
  44. :return:
  45. """
  46. self.resize( 1000, 600)
  47. self.center()
  48. self.show()
  49. def _init_ui_2(self):
  50. """
  51. 使用 绝对位置 布局元素位置
  52. :return:
  53. """
  54. lbl1 = QLabel( 'Zetcode', self)
  55. lbl1.move( 15, 10)
  56. lbl2 = QLabel( 'tutorials', self)
  57. lbl2.move( 35, 40)
  58. lbl3 = QLabel( 'for programmers', self)
  59. lbl3.move( 55, 70)
  60. self.setGeometry( 300, 300, 250, 150)
  61. self.setWindowTitle( 'Absolute')
  62. self.show()
  63. def _init_ui_3(self):
  64. """
  65. 使用布局 来 布局 元素位置
  66. :return:
  67. """
  68. btn_ok = QPushButton( "OK")
  69. btn_cancel = QPushButton( "Cancel")
  70. hbox = QHBoxLayout()
  71. hbox.addStretch( 1)
  72. hbox.addWidget(btn_ok)
  73. hbox.addWidget(btn_cancel)
  74. vbox = QVBoxLayout()
  75. vbox.addStretch( 1)
  76. vbox.addLayout(hbox)
  77. self.setLayout(vbox)
  78. self.setGeometry( 300, 300, 300, 150)
  79. self.setWindowTitle( 'Buttons')
  80. self.show()
  81. def _init_ui_4(self):
  82. """
  83. 使用 网格布局 来 布局 元素位置
  84. :return:
  85. """
  86. grid = QGridLayout()
  87. self.setLayout(grid)
  88. names = [
  89. 'Cls', 'Bck', '', 'Close',
  90. '7', '8', '9', '/',
  91. '4', '5', '6', '*',
  92. '1', '2', '3', '-',
  93. '0', '.', '=', '+'
  94. ]
  95. positions = [(i, j) for i in range( 5) for j in range( 4)]
  96. for position, name in zip(positions, names):
  97. if name == '':
  98. continue
  99. button = QPushButton(name)
  100. grid.addWidget(button, *position)
  101. self.move( 300, 150)
  102. self.setWindowTitle( 'Calculator')
  103. self.show()
  104. def _init_ui_5(self):
  105. """
  106. 网格布局 跨越 多行 或者 多列
  107. :return:
  108. """
  109. title = QLabel( 'Title')
  110. author = QLabel( 'Author')
  111. review = QLabel( 'Review')
  112. titleEdit = QLineEdit()
  113. authorEdit = QLineEdit()
  114. reviewEdit = QTextEdit()
  115. grid = QGridLayout()
  116. grid.setSpacing( 10)
  117. grid.addWidget(title, 1, 0)
  118. grid.addWidget(titleEdit, 1, 1)
  119. grid.addWidget(author, 2, 0)
  120. grid.addWidget(authorEdit, 2, 1)
  121. grid.addWidget(review, 3, 0)
  122. grid.addWidget(reviewEdit, 3, 1, 5, 1)
  123. self.setLayout(grid)
  124. self.setGeometry( 300, 300, 350, 300)
  125. self.setWindowTitle( 'Review')
  126. self.show()
  127. def closeEvent(self, event):
  128. """
  129. 重写关闭窗口事件
  130. :param event:
  131. :return:
  132. """
  133. reply = QMessageBox.question(
  134. self, 'Message', 'Are you sure close window ?',
  135. QMessageBox.Yes | QMessageBox.No, QMessageBox.No
  136. )
  137. if reply == QMessageBox.Yes:
  138. event.accept()
  139. else:
  140. event.ignore()
  141. pass
  142. class MyForm2(QMainWindow):
  143. """
  144. QMainWindow 类提供了一个主要的应用程序窗口。
  145. 你用它可以让应用程序添加状态栏,工具栏和菜单栏。
  146. """
  147. def __init__(self):
  148. super(MyForm2, self).__init__()
  149. # self._init_ui_6()
  150. # self._init_ui_7()
  151. # self._init_ui_8()
  152. self._init_ui_9()
  153. def _init_ui_6(self):
  154. """
  155. 状态栏
  156. :return:
  157. """
  158. self.statusBar().showMessage( 'Ready')
  159. self.setGeometry( 800, 300, 250, 150)
  160. self.setWindowTitle( 'Statusbar')
  161. self.show()
  162. def _init_ui_7(self):
  163. """
  164. 菜单栏
  165. :return:
  166. """
  167. # QAction可以操作菜单栏,工具栏,或自定义键盘快捷键。
  168. # 创建一个事件和一个特定的图标和一个“退出”的标签。
  169. exitAction = QAction(QIcon( 'exit.png'), '&Exit', self)
  170. exitAction.setShortcut( 'Ctrl+Q') # 定义该操作的快捷键。
  171. # 创建一个鼠标指针悬停在该菜单项上时的提示。
  172. exitAction.setStatusTip( 'Exit application')
  173. # # 第三行创建一个鼠标指针悬停在该菜单项上时的提示。
  174. exitAction.triggered.connect(qApp.quit)
  175. self.statusBar()
  176. # 创建一个菜单栏
  177. menubar = self.menuBar()
  178. # 添加菜单
  179. fileMenu = menubar.addMenu( '&File')
  180. # 添加事件
  181. fileMenu.addAction(exitAction)
  182. self.setGeometry( 800, 300, 300, 200)
  183. self.setWindowTitle( 'Menubar')
  184. self.show()
  185. def _init_ui_8(self):
  186. """
  187. 工具栏
  188. :return:
  189. """
  190. exitAction = QAction(QIcon( 'exit24.png'), 'Exit', self)
  191. exitAction.setShortcut( 'Ctrl+Q')
  192. exitAction.triggered.connect(qApp.quit)
  193. self.toolbar = self.addToolBar( 'Exit')
  194. self.toolbar.addAction(exitAction)
  195. self.setGeometry( 800, 300, 300, 200)
  196. self.setWindowTitle( 'Toolbar')
  197. self.show()
  198. def _init_ui_9(self):
  199. # 创建一个菜单条,工具栏和状态栏的小窗口
  200. textEdit = QTextEdit()
  201. self.setCentralWidget(textEdit)
  202. exitAction = QAction(QIcon( 'exit24.png'), 'Exit', self)
  203. exitAction.setShortcut( 'Ctrl+Q')
  204. exitAction.setStatusTip( 'Exit application')
  205. exitAction.triggered.connect(self.close)
  206. self.statusBar()
  207. menubar = self.menuBar()
  208. fileMenu = menubar.addMenu( '&File')
  209. fileMenu.addAction(exitAction)
  210. toolbar = self.addToolBar( 'Exit')
  211. toolbar.addAction(exitAction)
  212. self.setGeometry( 800, 300, 350, 250)
  213. self.setWindowTitle( 'Main window')
  214. self.show()
  215. if __name__ == '__main__':
  216. app = QApplication(sys.argv)
  217. form_1 = MyForm1()
  218. form_2 = MyForm2()
  219. sys.exit(app.exec_())
  220. pass

点击产生一个新窗口:


     
     
  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton
  3. class Form1(QWidget):
  4. def __init__(self):
  5. super(Form1, self).__init__()
  6. self.setWindowTitle( 'From_1')
  7. self.resize( 600, 300)
  8. self._init_ui()
  9. self.show()
  10. def close_window(self):
  11. """
  12. 点击按钮 将 窗体1 关掉
  13. :return:
  14. """
  15. self.close()
  16. def _init_ui(self):
  17. v_box = QVBoxLayout()
  18. self.btn_1 = QPushButton( 'btn_1: close Form_2')
  19. self.btn_2 = QPushButton( 'btn_2: show Form_2')
  20. v_box.addWidget(self.btn_1)
  21. v_box.addWidget(self.btn_2)
  22. self.setLayout(v_box)
  23. class Form2(QWidget):
  24. def __init__(self):
  25. super(Form2, self).__init__()
  26. self.setWindowTitle( 'From_2')
  27. self.resize( 800, 400)
  28. self._init_ui()
  29. def display(self):
  30. """
  31. 显示窗体
  32. :return:
  33. """
  34. self.show()
  35. def _init_ui(self):
  36. h_box = QHBoxLayout()
  37. btn_3 = QPushButton( 'btn_3')
  38. btn_4 = QPushButton( 'btn_4')
  39. h_box.addWidget(btn_3)
  40. h_box.addWidget(btn_4)
  41. self.setLayout(h_box)
  42. if __name__ == '__main__':
  43. app = QApplication(sys.argv)
  44. w1 = Form1()
  45. w2 = Form2()
  46. w1.show()
  47. w1.btn_1.clicked.connect(w1.close_window)
  48. w1.btn_2.clicked.connect(w2.display)
  49. app.exec_()

布局示例:

PyQt入门(五)— 布局:https://blog.csdn.net/qq_34710142/article/details/80875625


     
     
  1. from PyQt5 import QtWidgets
  2. class MyWindow(QtWidgets.QWidget):
  3. def __init__(self):
  4. super().__init__()
  5. self.setWindowTitle( '嵌套布局示例')
  6. # 开始:
  7. wlayout = QtWidgets.QHBoxLayout() # 全局布局(1个):水平
  8. hlayout = QtWidgets.QHBoxLayout() # 局部布局(4个):水平、竖直、网格、表单
  9. vlayout = QtWidgets.QVBoxLayout()
  10. glayout = QtWidgets.QGridLayout()
  11. flayout = QtWidgets.QFormLayout()
  12. hlayout.addWidget(QtWidgets.QPushButton(str( 1))) # 局部布局添加部件(例如:按钮)
  13. hlayout.addWidget(QtWidgets.QPushButton(str( 2)))
  14. vlayout.addWidget(QtWidgets.QPushButton(str( 3)))
  15. vlayout.addWidget(QtWidgets.QPushButton(str( 4)))
  16. glayout.addWidget(QtWidgets.QPushButton(str( 5)), 0, 0)
  17. glayout.addWidget(QtWidgets.QPushButton(str( 6)), 0, 1)
  18. glayout.addWidget(QtWidgets.QPushButton(str( 7)), 1, 0)
  19. glayout.addWidget(QtWidgets.QPushButton(str( 8)), 1, 1)
  20. flayout.addWidget(QtWidgets.QPushButton(str( 9)))
  21. flayout.addWidget(QtWidgets.QPushButton(str( 10)))
  22. flayout.addWidget(QtWidgets.QPushButton(str( 11)))
  23. flayout.addWidget(QtWidgets.QPushButton(str( 12)))
  24. hwg = QtWidgets.QWidget() # 准备四个部件
  25. vwg = QtWidgets.QWidget()
  26. gwg = QtWidgets.QWidget()
  27. fwg = QtWidgets.QWidget()
  28. hwg.setLayout(hlayout) # 四个部件设置局部布局
  29. vwg.setLayout(vlayout)
  30. gwg.setLayout(glayout)
  31. fwg.setLayout(flayout)
  32. wlayout.addWidget(hwg) # 四个部件加至全局布局
  33. wlayout.addWidget(vwg)
  34. wlayout.addWidget(gwg)
  35. wlayout.addWidget(fwg)
  36. self.setLayout(wlayout) # 窗体本尊设置全局布局
  37. if __name__ == "__main__":
  38. import sys
  39. app = QtWidgets.QApplication(sys.argv)
  40. win = MyWindow()
  41. win.show()
  42. sys.exit(app.exec_())

效果:

嵌套布局示例

 

 

布局 时 需要注意点

 

继承 QMainWindow 时布局界面 继承 QWidget 时 布局界面 是不一样的

 

1. 继承 QMainWindow 时 的界面布局

如何给QMainWindow正确地设置布局( C++ 示例 步骤)

  1. 第一步:创建一个QWidget实例,并将这个实例设置为 centralWidget:
        QWidget *widget = new QWidget();
        this->setCentralWidget(widget);
  2. 第二部:创建一个主布局mainLayout,并把所需要的所有控件都往里面放(工具栏、菜单栏、状态栏除外):
        QHBoxLayout *mainLayout = new QHBoxLayout;
        mainLayout->addWidget(...);
        mainLayout->addLayout(...);
        ...
  3. 第三步:将 widget 的布局设置为 mainLayout:
        centralWidget()->setLayout(mainLayout);
        //centralWidget()返回的是第一步创建的那个QWidget实例

继承 QMainWindow 时,需要设置 中心部件(即 主界面),如下面代码需要添加三行代码:


     
     
  1. main_widget = QWidget() # 界面 实例
  2. self.setCentralWidget(main_widget) # 设置 为 中心界面
  3. ......
  4. ......
  5. self.centralWidget().setLayout(v_box) # 设置中心界面的布局

根据 C++ 示例 步骤改成 python ,完整示例代码如下:


     
     
  1. import sys
  2. # QMainWindow 类提供了一个主要的应用程序窗口。
  3. # 你用它可以让应用程序添加状态栏,工具栏和菜单栏。
  4. from PyQt5.QtWidgets import QWidget, QMainWindow
  5. from PyQt5.QtWidgets import (
  6. QApplication, QDesktopWidget, QHBoxLayout, QVBoxLayout,
  7. QPushButton, QListView,
  8. )
  9. class LayoutDemoByQMainWindow(QMainWindow):
  10. def __init__(self):
  11. super(LayoutDemoByQMainWindow, self).__init__()
  12. self.resize( 1000, 600) # 重置大小
  13. self._center_display() # 中心显示
  14. self.vertical_layout()
  15. self.show()
  16. def _center_display(self):
  17. """
  18. 控制窗口显示在屏幕中心的方法
  19. :return:
  20. """
  21. # 获得窗口
  22. qr = self.frameGeometry()
  23. # 获得屏幕中心点
  24. cp = QDesktopWidget().availableGeometry().center()
  25. # 显示到屏幕中心
  26. qr.moveCenter(cp)
  27. self.move(qr.topLeft())
  28. def vertical_layout(self):
  29. """
  30. 垂直布局
  31. :return:
  32. """
  33. ###################################
  34. main_widget = QWidget()
  35. self.setCentralWidget(main_widget)
  36. ###################################
  37. h_box_1 = QHBoxLayout()
  38. h_box_2 = QHBoxLayout()
  39. h_box_3 = QHBoxLayout()
  40. btn_ok = QPushButton( 'Ok', self)
  41. btn_cancel = QPushButton( 'Cancel', self)
  42. btn_exit = QPushButton( 'Exit', self)
  43. btn_ok.resize( 10, 10)
  44. btn_cancel.resize( 10, 10)
  45. btn_exit.resize( 40, 10)
  46. # h_box_1.addStretch(1)
  47. h_box_1.addWidget(btn_ok)
  48. h_box_1.addWidget(btn_cancel)
  49. h_box_1.addWidget(btn_exit)
  50. list_view = QListView(self)
  51. h_box_2.addWidget(list_view)
  52. btn_1 = QPushButton( 'btn_1', self)
  53. btn_2 = QPushButton( 'btn_2', self)
  54. btn_3 = QPushButton( 'btn_3', self)
  55. h_box_3.addStretch( 1)
  56. h_box_3.addWidget(btn_1)
  57. h_box_3.addWidget(btn_2)
  58. h_box_3.addWidget(btn_3)
  59. v_box = QVBoxLayout()
  60. v_box.addLayout(h_box_1)
  61. v_box.addLayout(h_box_2)
  62. v_box.addLayout(h_box_3)
  63. ###################################
  64. self.centralWidget().setLayout(v_box)
  65. ###################################
  66. pass
  67. if __name__ == '__main__':
  68. app = QApplication(sys.argv)
  69. # form_1 = LayoutDemoByQWidget()
  70. form = LayoutDemoByQMainWindow()
  71. sys.exit(app.exec_())
  72. pass

示例代码 2:


     
     
  1. from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit, QWidget, QVBoxLayout, QFrame
  2. from PyQt5.Qt import QSize
  3. import sys
  4. class Example(QMainWindow):
  5. def __init__(self):
  6. super(Example, self).__init__()
  7. self._init_ui()
  8. def _init_ui(self):
  9. # 控件随窗口改变而改变
  10. # 可以通过继承 QMainWindow 来实现
  11. self.resize( 400, 400)
  12. # 建立顶层控件
  13. self.centeralwidget = QWidget()
  14. self.v_box = QVBoxLayout(self.centeralwidget)
  15. edit = QTextEdit()
  16. self.v_box.addWidget(edit)
  17. # 通过设置中心控件,将子控件填充布局
  18. # 如果有多个控件最好在加一层widget这样最好布局,控制
  19. self.setCentralWidget(self.centeralwidget)
  20. self.show()
  21. if __name__ == '__main__':
  22. app = QApplication(sys.argv)
  23. ex = Example()
  24. sys.exit(app.exec_())

示例代码 3:


     
     
  1. from PyQt5 import QtWidgets
  2. import sys
  3. # 主窗口类
  4. class MainWidget(QtWidgets.QMainWindow):
  5. def __init__(self):
  6. super().__init__()
  7. self.resize( 500, 300)
  8. self.setWindowTitle( "") # 设置窗口标题
  9. main_widget = QtWidgets.QWidget() # 实例化一个widget部件
  10. main_layout = QtWidgets.QGridLayout() # 实例化一个网格布局层
  11. main_widget.setLayout(main_layout) # 设置主widget部件的布局为网格布局
  12. self.setCentralWidget(main_widget) # 设置窗口默认部件为主widget
  13. if __name__ == '__main__':
  14. app = QtWidgets.QApplication(sys.argv)
  15. gui = MainWidget()
  16. gui.show()
  17. sys.exit(app.exec_())

 

 

2. 继承 QWidget 时 的界面布局

继承 Qwidget 时,不需要设置中心部件,直接布局就行。最后把 Qwidget 的布局设置成 你自己的布局即可。

        self.setLayout(v_box)

完成示例代码:


     
     
  1. import sys
  2. # QMainWindow 类提供了一个主要的应用程序窗口。
  3. # 你用它可以让应用程序添加状态栏,工具栏和菜单栏。
  4. from PyQt5.QtWidgets import QWidget
  5. from PyQt5.QtWidgets import (
  6. QApplication, QDesktopWidget, QHBoxLayout, QVBoxLayout,
  7. QPushButton, QListView,
  8. )
  9. class LayoutDemoByQWidget(QWidget):
  10. def __init__(self):
  11. super(LayoutDemoByQWidget, self).__init__()
  12. self.resize( 1000, 600) # 重置大小
  13. self._center_display() # 中心显示
  14. self.vertical_layout()
  15. self.show()
  16. def _center_display(self):
  17. """
  18. 控制窗口显示在屏幕中心的方法
  19. :return:
  20. """
  21. # 获得窗口
  22. qr = self.frameGeometry()
  23. # 获得屏幕中心点
  24. cp = QDesktopWidget().availableGeometry().center()
  25. # 显示到屏幕中心
  26. qr.moveCenter(cp)
  27. self.move(qr.topLeft())
  28. def vertical_layout(self):
  29. """
  30. 垂直布局
  31. :return:
  32. """
  33. h_box_1 = QHBoxLayout()
  34. h_box_2 = QHBoxLayout()
  35. h_box_3 = QHBoxLayout()
  36. btn_ok = QPushButton( 'Ok', self)
  37. btn_cancel = QPushButton( 'Cancel', self)
  38. btn_exit = QPushButton( 'Exit', self)
  39. btn_ok.resize( 10, 10)
  40. btn_cancel.resize( 10, 10)
  41. btn_exit.resize( 40, 10)
  42. # h_box_1.addStretch(1)
  43. h_box_1.addWidget(btn_ok)
  44. h_box_1.addWidget(btn_cancel)
  45. h_box_1.addWidget(btn_exit)
  46. list_view = QListView(self)
  47. h_box_2.addWidget(list_view)
  48. btn_1 = QPushButton( 'btn_1', self)
  49. btn_2 = QPushButton( 'btn_2', self)
  50. btn_3 = QPushButton( 'btn_3', self)
  51. h_box_3.addStretch( 1)
  52. h_box_3.addWidget(btn_1)
  53. h_box_3.addWidget(btn_2)
  54. h_box_3.addWidget(btn_3)
  55. v_box = QVBoxLayout()
  56. # v_box.addStretch(1)
  57. v_box.addLayout(h_box_1)
  58. v_box.addLayout(h_box_2)
  59. v_box.addLayout(h_box_3)
  60. # 把 默认布局 设置成 v_box
  61. self.setLayout(v_box)
  62. pass
  63. if __name__ == '__main__':
  64. app = QApplication(sys.argv)
  65. form = LayoutDemoByQWidget()
  66. sys.exit(app.exec_())
  67. pass

 

 

一篇文章让你读懂PyQt5布局管理,绝对干货

 

From:https://cloud.tencent.com/developer/article/1437295

python爬虫实战之路:https://cloud.tencent.com/developer/column/4821

pyqt5 - 布局控件 https://www.cnblogs.com/liming19680104/p/10356142.html

Python 图形开发:PyQt 三种界面布局解析:http://www.codebelief.com/article/2017/04/python-gui-development-pyqt-three-kinds-of-layout/

Qt 之水平/垂直布局(QBoxLayout、QHBoxLayout、QVBoxLayout):https://blog.csdn.net/liang19890820/article/details/51537246

PyQt5 布局大全:https://blog.csdn.net/jeekmary/article/details/80208601

PyQt5之布局管理:https://www.cnblogs.com/laizhenghong2012/p/10040798.html

窗体的四个角布局:http://www.bubuko.com/infodetail-2838999.html

继承图:

在布局中添加控件用addWidght(),添加布局用addLayout()

 

PyQt5 的界面布局主要有两种方法:绝对定位和局部类。在PyQt5中有四种布局方式:水平布局、垂直布局、网格布局、表单布局。还有两种布局方法:addLayout和addWidget,其中addLayout用于在布局中插入子布局,addWidget用于在布局中插入控件。

  • 垂直布局:控件默认按照从上到下的顺序进行纵向添加。
  • 水平布局:控件默认按照从左到右的顺序进行横向添加。
  • 栅格布局:将窗口分为若干行(row)和列(column)。
  • 表单布局:控件以两列的形式布局在窗口中,左边为标签,右边为输入控件。

 

使用布局管理器

 

  1. 绝对布局 这个就不详细说明了,使用 QWidget 的 move、setGeometry 等方法,直接设置其在窗口中的位置。
  2. 盒子布局(QHBoxLayout 水平布局、QVBoxLayout 垂直布局) 方法:
    • stretch(伸缩量),只适用于QBoxLayout布局方式,控件和窗口会随着伸缩量的变大而增加
    • alignment,指定对齐方式
    • addLayout(self, QLayout, stretch=0) 在窗口的右边添加布局,使用stretch(伸缩量)进行伸缩,默认为0
    • addWidget(self, QWidget, stretch, Qt.Alignment) 在布局中添加控件。
  3. QGridLayout 栅格布局(网格布局) 方法:
    • addLayout(QLayout, row, column, Qt.Alignment) 在栅格布局的行(row)、列(column)位置添加新的布局,并设置对齐方式
    • addLayout(QLayout, row, column, rowSpan, columnSpan, Qt.Alignment) 在栅格布局中新的布局,从行(row)、列(column)开始,占据rowSpan行、columnSpan列
    • addWidget(QWidget, row, column, Qt.Alignment) 在栅格布局的行(row)、列(column)中添加窗口控件,
    • addWidget(QWidget, fromRow, fromColumn, rowSpan, columnSpan, Qt.Alignment) 在栅格布局中添加窗口控件,从行(row)、列(column)开始,占据rowSpan行、columnSpan列
    • setRowStretch(row, stretch) 在行(row)处添加伸缩量
    • setColumnStretch(column, stretch) 在列(column)处添加伸缩量
  4. QFormLayout 表单布局 方法:
    • addRow(QWidget, QWidget)
    • addRow(QWidget, QLayout)
    • addRow(str, QWidget)
    • addRow(str, QLayout) 以上在表单布局最后添加一行数据,设置表单的标签和控件
    • addRow(QWidget)
    • addRow(QLayout) QWidget和QLayout添加在最后一行,并占据两列宽度
    • insertRow(row, QWidget, QWidget)
    • insertRow(row, QWidget, QLayout)
    • insertRow(row, str, QWidget)
    • insertRow(row, str, QLayout) 在指定行添加标签和控件
    • insertRow(row, QWidget)
    • insertRow(row, QLayout) 在指定行添加控件,并占据两列宽度

 

盒布局名字虽然听起来怪怪的,但是却非常形象,主要借助两个函数QHBoxLayout(水平方向)和QVBoxLayout(竖直方向),建立一个个水平方向或者是竖直方向的“盒子”,盒子本身整齐排列,同时把盒子内部的组件也整齐排列,这样整体来看就显得会很整齐。就像小时候写作业一样,放置内容之前之间先给你把区域划好了。

一个盒布局实例

示例代码:


     
     
  1. import sys
  2. from PyQt5.QtWidgets import (QWidget, QPushButton,
  3. QHBoxLayout, QVBoxLayout, QApplication,QMainWindow)
  4. class Example(QWidget):
  5. def __init__(self):
  6. super().__init__()
  7. self.initUI()
  8. def initUI(self):
  9. # 添加5个按钮
  10. Button1 = QPushButton( "按钮1")
  11. Button2 = QPushButton( "按钮2")
  12. Button3 = QPushButton( "按钮3")
  13. Button4 = QPushButton( "按钮4")
  14. Button5 = QPushButton( "按钮5")
  15. #添加一个竖直盒子,两个水平盒子
  16. hbox1 = QHBoxLayout()
  17. hbox2 = QHBoxLayout()
  18. # hbox = QHBoxLayout()
  19. vbox = QVBoxLayout()
  20. #把按钮放在盒子里
  21. vbox.addWidget(Button1)
  22. vbox.addWidget(Button2)
  23. vbox.addWidget(Button3)
  24. hbox2.addWidget(Button4)
  25. hbox2.addWidget(Button5)
  26. #把竖直盒子和水平盒子嵌套在水平盒子中
  27. hbox1.addLayout(vbox)
  28. hbox1.addLayout(hbox2)
  29. self.setLayout(hbox1)
  30. self.setGeometry( 400, 400, 600, 300)
  31. self.setWindowTitle( '盒布局示例')
  32. self.show()
  33. if __name__ == '__main__':
  34. app = QApplication(sys.argv)
  35. ex = Example()
  36. sys.exit(app.exec_())

效果如下:

这里写图片描述

在盒布局里,还有一个特别有用的函数:布局.addStretch(int)。这个函数很形象,就是在布局之内添加一个弹簧,使组件之间有空隙。int值代表“弹簧”的长度。

在QT Designer中,你可以看到这个组件就是一个弹簧样子的。

这里写图片描述

需要注意的是:弹簧控件是按照这个弹簧的比例分的,比如:


     
     
  1. hbox.addStretch( 1) #hbox是一个水平“盒子”
  2. hbox.addWidget(Button1)
  3. hbox.addStretch( 1)
  4. hbox.addWidget(Button2)
  5. hbox.addStretch( 1)

就是把hbox这个盒子剩余空间等分成三份,如果把中间的弹簧改成2,那么就是把这个盒子剩余空间等分成4分,中间的空间占两份。对比如下:

这里写图片描述

 

布局对齐方式:

参数

描述

QtCore.Qt.AlignLeft

水平方向居左对齐

QtCore.Qt.AlignRight

水平方向居右对齐

QtCore.Qt.AlignCenter

水平方向居中对齐

QtCore.Qt.AlignJustify

水平方向两端对齐

QtCore.Qt.AlignTop

垂直方向靠上对齐

QtCore.Qt.AlignBottom

垂直方向靠下对齐

QtCore.Qt.AlignVCenter

垂直方向居中对齐

间距


     
     
  1. addSpacing(self, int)    # 设置各控件的上下间距,通过该方法可以增加额外的控件
  2. addStretch(self, int)      # 分配布局大小比例
  3. insertStretch(index, stretch = 0)    # 在指定控件间隔处添加布局比例
  4. insertSpacing(index, size)    #在指定控件间隔处设置间隔大小

addStretch 是按照比例来调整界面布局,在页面布局中使用广泛,所以我们要使用一定的篇幅来进行代码测试。

使用 addStretch,我们可以实现各种对齐方式,而且更加灵活。


     
     
  1. import sys
  2. from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QHBoxLayout
  3. class Example(QWidget):
  4. def __init__(self):
  5. super().__init__()
  6. self.initUI()
  7. def initUI(self):
  8. layout = QHBoxLayout()
  9. layout.addWidget(QPushButton(str( 1)))
  10. layout.addWidget(QPushButton(str( 2)))
  11. self.setLayout(layout)
  12. self.setGeometry( 300, 300, 400, 100)
  13. self.setWindowTitle( "Buttons")
  14. if __name__ == "__main__":
  15. app = QApplication(sys.argv)
  16. ex = Example()
  17. ex.show()
  18. sys.exit(app.exec_())

默认是所有控件撑满整个布局文件。运行结果截图:

 

按比例布局:


     
     
  1. layout.addWidget(btn)
  2. layout.addWidget(tableWidget)
  3. layout.addLayout(h_layout)
  4. layout.setStretchFactor(btn, 1)
  5. layout.setStretchFactor(tableWidget, 2)
  6. layout.setStretchFactor(h_layout, 2)

调用 setStretchFactor 函数后,三个控件的比例分别为:1:2:2

 

  • 水平居左对齐 ~ QtCore.Qt.AlignLeft

     
     
  1. def initUI(self):
  2. layout = QHBoxLayout()
  3. layout.addWidget(QPushButton(str( 1))
  4. layout.addWidget(QPushButton(str( 2))
  5. layout.addStretch( 1) # 新增这一行。把 剩余空间分成一份,最后添加这一份的间隔
  6. ......

在两个控件后增加这一行,相当于水平布局中存在:按钮1按钮2stretch。此时 addStretch 的参数只要大于0,则表示占满整个布局最后一部分,前面的控件显示为正常大小,不要拉伸。

 

  • 水平居右对齐 ~ QtCore.Qt.AlignRight

     
     
  1. def initUI(self):
  2. layout = QHBoxLayout()
  3. layout.addStretch( 1) # 新增这一行在控件前面
  4. layout.addWidget(QPushButton(str( 1))
  5. layout.addWidget(QPushButton(str( 2))
  6. ......

这一行加入到布局中所有控件之前,相当于水平布局中存在:stretch-按钮1-按钮2,表示占满整个布局的最开始部分,后面的控件显示为正常大小,不要拉伸。

 

  • 水平居中对齐 ~ QtCore.Qt.AlignCenter

     
     
  1. def initUI(self):
  2. layout = QHBoxLayout()
  3. layout.addStretch( 1) # 前面增加一行
  4. layout.addWidget(QPushButton(str( 1))
  5. layout.addWidget(QPushButton(str( 2))
  6. layout.addStretch( 1) #后面增加一行
  7. ......

stretch按钮1按钮2stretch,表示左右两边充满,控件占据中间位置

 

注意:当一个布局中出现多个addStretch时,后面的参数就有意义了,其表示整个布局的大小减去控件总大小进行n等份分配。

例如:


     
     
  1. def initUI(self):
  2. layout = QHBoxLayout()
  3. layout.addStretch( 1) # 注意1
  4. layout.addWidget(QPushButton(str( 1))
  5. layout.addWidget(QPushButton(str( 2))
  6. layout.addStretch( 3) # 注意2

表示除去控件1、控件2 的宽度,剩余部分四等份,前面占据一份,最后面占据三份

 

  • 水平两端对齐 ~ QtCore.Qt.AlignJustify

     
     
  1. def initUI(self):
  2. layout = QHBoxLayout()
  3. layout.addWidget(QPushButton(str( 1))
  4. layout.addStretch( 1) # 添加行
  5. layout.addWidget(QPushButton(str( 2))

 

  • 垂直顶部对齐 ~ QtCore.Qt.AlignTop

     
     
  1. def initUI(self):
  2. layout = QVBoxLayout()
  3. layout.addWidget(QPushButton(str( 1))
  4. layout.addWidget(QPushButton(str( 2))
  5. layout.addStretch( 1) # 添加行

 

  • 垂直底部对齐 ~ QtCore.Qt.AlignBottom

     
     
  1. def initUI(self):
  2. layout = QVBoxLayout()
  3. layout.addStretch( 1) # 添加行
  4. layout.addWidget(QPushButton(str( 1))
  5. layout.addWidget(QPushButton(str( 2))

 

  • 垂直居中对齐 ~ QtCore.Qt.AlignVCenter

     
     
  1. def initUI(self):
  2. layout = QVBoxLayout()
  3. layout.addStretch( 1) # 添加行
  4. layout.addWidget(QPushButton(str( 1))
  5. layout.addWidget(QPushButton(str( 2))
  6. layout.addStretch( 1) # 添加行

 

  • 垂直两端对齐

     
     
  1. def initUI(self):
  2. layout = QVBoxLayout()
  3. layout.addWidget(QPushButton(str( 1))
  4. layout.addStretch( 1) # 添加行
  5. layout.addWidget(QPushButton(str( 2))

 

如果要进行组合布局,例如左上角、右下角等,如下:


     
     
  1. def initUI(self):
  2. layout1 = QHBoxLayout()
  3. layout1.addWidget(QPushButton(str( 1))
  4. layout1.addWidget(QPushButton(str( 2))
  5. layout1.addStretch( 1) # 水平居左
  6. layout2 = QVBoxLayout()
  7. layout2.addLayout(layout1)
  8. layout2.addStretch( 1) # 垂直顶部对齐
  9. self.setLayout(layout2)
  10. ......

 

addSpacing

addSpacing是设置控件之间的间距。就按照图1的布局及代码进行演示。


     
     
  1. def initUI(self):
  2. layout = QHBoxLayout()
  3. layout.addWidget(QPushButton(str( 1))
  4. layout.addSpacing( 100)
  5. layout.addWidget(QPushButton(str( 2))

间距设置可以放置在任何地方,对于调整控件位置十分有效。相当于在控件之间添加了一个空的控件。详细的用法与addStrech类似,参考以上使用即可。

 

QSplitter

控件大小占比不固定,可以通过拖拽两个控件的边界改变控件占比大小


     
     
  1. import sys
  2. from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QFrame,
  3. QSplitter, QTextEdit, QApplication)
  4. from PyQt5.QtCore import Qt
  5. class SplitterExample(QWidget):
  6. def __init__(self):
  7. super(SplitterExample, self).__init__()
  8. self.initUI()
  9. def initUI(self):
  10. # 初始化控件
  11. topleft = QFrame()
  12. topleft.setFrameShape(QFrame.StyledPanel)
  13. bottom = QFrame()
  14. bottom.setFrameShape(QFrame.StyledPanel)
  15. textedit = QTextEdit()
  16. # 设置第一个Splitter的布局方向
  17. splitter1 = QSplitter(Qt.Horizontal)
  18. # 为第一个Splitter添加控件,并设置两个控件所占空间大小
  19. splitter1.addWidget(topleft)
  20. splitter1.addWidget(textedit)
  21. splitter1.setSizes([ 100, 200])
  22. # 设置第二个Splitter的布局方向,将第一个Splitter嵌套在第二个里
  23. splitter2 = QSplitter(Qt.Vertical)
  24. splitter2.addWidget(splitter1)
  25. splitter2.addWidget(bottom)
  26. # 设置全局布局
  27. hbox = QHBoxLayout(self)
  28. hbox.addWidget(splitter2)
  29. self.setLayout(hbox)
  30. self.setWindowTitle( 'QSplitter 例子')
  31. self.setGeometry( 300, 300, 300, 200)
  32. if __name__ == '__main__':
  33. app = QApplication(sys.argv)
  34. demo = SplitterExample()
  35. demo.show()
  36. sys.exit(app.exec_())

 

 

【第 5 节】PyQt5 事件 和 信号 演示代码

 

可以 把 __init__ 函数中的 注释逐个取消,然后运行程序看执行效果 ):


     
     
  1. # -*- coding: utf-8 -*-
  2. # @Author :
  3. # @File : main.py
  4. # @Software: PyCharm
  5. # @description : XXX
  6. import sys
  7. from PyQt5.QtCore import Qt
  8. from PyQt5.QtWidgets import (
  9. QWidget, QMainWindow, QLCDNumber, QSlider, QVBoxLayout, QApplication, QPushButton
  10. )
  11. from PyQt5.QtCore import pyqtSignal, QObject
  12. class Communicate(QObject):
  13. """
  14. 创建了一个名为closeApp的信号。
  15. 这个信号会在按下鼠标时触发,它连接着QMainWindow的close()插槽。
  16. """
  17. closeApp = pyqtSignal()
  18. # class MyForm(QWidget):
  19. class MyForm(QMainWindow):
  20. def __init__(self):
  21. super(MyForm, self).__init__()
  22. # self._init_ui_1()
  23. # self._init_ui_2()
  24. # self._init_ui_3()
  25. self._init_ui_4()
  26. def _init_ui_1(self):
  27. """
  28. 展示了一个QtGui.QLCDNumber和QtGui.QSlider。lcd的值会随着滑块的拖动而改变。
  29. :return:
  30. """
  31. lcd = QLCDNumber(self)
  32. sld = QSlider(Qt.Horizontal, self)
  33. vbox = QVBoxLayout()
  34. vbox.addWidget(lcd)
  35. vbox.addWidget(sld)
  36. self.setLayout(vbox)
  37. ##########################################################
  38. # 这里我们将滚动条的 valueChanged信号连接到lcd的display插槽。
  39. # sender是发出信号的对象。
  40. # receiver是接收信号的对象。
  41. # slot(插槽)是对信号做出反应的方法。
  42. sld.valueChanged.connect(lcd.display)
  43. ##########################################################
  44. self.setGeometry( 300, 300, 500, 300)
  45. self.setWindowTitle( 'Signal & slot')
  46. self.show()
  47. def _init_ui_2(self):
  48. self.setGeometry( 300, 300, 500, 300)
  49. self.setWindowTitle( 'Event handler')
  50. self.show()
  51. def keyPressEvent(self, e):
  52. """
  53. 重写 keyPressEvent 事件
  54. :param e:
  55. :return:
  56. """
  57. if e.key() == Qt.Key_Escape:
  58. self.close()
  59. def _init_ui_3(self):
  60. btn1 = QPushButton( "Button 1", self)
  61. btn1.move( 30, 50)
  62. btn2 = QPushButton( "Button 2", self)
  63. btn2.move( 150, 50)
  64. # 按钮的点击信号 连接到 槽(槽就是一个函数)buttonClicked
  65. # 两个按钮连接到了同一个插槽。
  66. btn1.clicked.connect(self.buttonClicked)
  67. btn2.clicked.connect(self.buttonClicked)
  68. self.statusBar()
  69. self.setGeometry( 300, 300, 500, 300)
  70. self.setWindowTitle( 'Event sender')
  71. self.show()
  72. def buttonClicked(self):
  73. # 通过调用sender()方法来判断当前按下的是哪个按钮
  74. sender = self.sender()
  75. # 通过调用sender()方法来判断信号源, 并将其名称显示在窗体的状态栏中。
  76. self.statusBar().showMessage(sender.text() + ' was pressed')
  77. def _init_ui_4(self):
  78. """
  79. 通过QObject创建的对象可以发出信号。
  80. 这个示例演示了如何发出自定义信号
  81. :return:
  82. """
  83. # 信号closeApp 是 Communicate的类属性,它由 pyqtSignal()创建。
  84. self.c = Communicate()
  85. # 自定义closeApp信号连接到QMainWindow的close槽
  86. # 当在窗体上点击鼠标时会触发closeApp信号,使程序退出。
  87. self.c.closeApp.connect(self.close)
  88. self.setGeometry( 1000, 300, 500, 300)
  89. self.setWindowTitle( 'Emit signal')
  90. self.show()
  91. def mousePressEvent(self, event):
  92. self.c.closeApp.emit()
  93. if __name__ == '__main__':
  94. app = QApplication(sys.argv)
  95. form = MyForm()
  96. sys.exit(app.exec_())
  97. pass

 

 

【第 6 节】对话框 演示代码

 

演示代码:


     
     
  1. import sys
  2. from PyQt5.QtWidgets import (
  3. QWidget, QMainWindow, QPushButton, QLineEdit, QInputDialog, QApplication, QFrame, QColorDialog,
  4. QVBoxLayout, QSizePolicy, QLabel, QFontDialog, QTextEdit, QAction, QFileDialog
  5. )
  6. from PyQt5.QtGui import QColor
  7. from PyQt5.QtGui import QIcon
  8. # class MyForm(QWidget):
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值