注:原创不易,转载请务必注明原作者和出处,感谢支持!

一 写在开头

1.1 本文内容

本文的主要内容:PyQt中的窗口部件:QMainWindow,QWidget,QDialog。

上述三种窗口部件都是用来创建窗口的,可以直接使用,也可以继承后再使用。它们的异同如下:

  • QMainWindow窗口可以包含菜单栏、工具栏、状态栏、标题栏等,是最常见的窗口形式,是GUI程序的主窗口。
  • QDialog是对话框窗口的基类。对话框主要用来执行短期任务,或者与用户进行互动,它可以是模态的,也可是非模态的。QDialog窗口没有菜单栏、工具栏、状态栏等。
  • QWidget即可以用来作为顶层窗口(QMainWindow),可以嵌入到其他窗口中。

三者之间的继承关系如下图:

graph TD;
QWidget-->QMainWindow;
QWidget-->QDialog;

二 QMainWindow

2.1 知识铺垫

何为顶层窗口?如果一个窗口包含一个或多个窗口,那么这个窗口就是父窗口,被包含的窗口则是子窗口。没有父窗口的窗口则是顶层窗口。QMainWindow就是一个顶层窗口,它可以包含很多界面元素,如菜单栏、工具栏、状态栏、子窗口等等。QMainWindow元素布局如下图(来自Qt文档)。

QMainWindow常用的方法有:

方法 描述
addToolBar() 添加工具栏
centralWidget() 返回窗口中心的控件,未设置时返回NULL
menuBar() 返回主窗口的菜单栏
setCentralWidget() 设置窗口中心的控件
setStatusBar() 设置状态栏
statusBar() 获得状态栏对象后,调用状态栏对象的showMessage()方法显示状态栏信息

2.2 QMainWindow实例

什么也不设置的“空白”QMainWindow,代码及效果图如下所示。

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QApplication, QMainWindow if __name__ == '__main__':
app = QApplication(sys.argv)
w = QMainWindow()
w.show()
sys.exit(app.exec_())

我们通过一个仿照Windows系统的中记事本程序的小实例来了解QMainWindow的使用。

# text-editor.py

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
import webbrowser
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QMainWindow, QTextEdit, QAction, QApplication, \
QMessageBox, QFileDialog, QDesktopWidget class TextEditor(QMainWindow):
'''
TextEditor : 一个简单的记事本程序
'''
def __init__(self):
super().__init__()
self.copiedText = ''
self.initUI() # 初始化窗口界面
def initUI(self):
# 设置中心窗口部件为QTextEdit
self.textEdit = QTextEdit()
self.setCentralWidget(self.textEdit)
self.textEdit.setText('') # 定义一系列的Action
# 退出
exitAction = QAction(QIcon('./images/exit.png'), 'Exit', self)
exitAction.setShortcut('Ctrl+Q')
exitAction.setStatusTip('Exit application')
exitAction.triggered.connect(self.close) # 新建
newAction = QAction(QIcon('./images/new.png'), 'New', self)
newAction.setShortcut('Ctrl+N')
newAction.setStatusTip('New application')
newAction.triggered.connect(self.__init__) # 打开
openAction = QAction(QIcon('./images/open.png'), 'Open', self)
openAction.setShortcut('Ctrl+O')
openAction.setStatusTip('Open Application')
openAction.triggered.connect(self.open) # 保存
saveAction = QAction(QIcon('./images/save.png'), 'Save', self)
saveAction.setShortcut('Ctrl+S')
saveAction.setStatusTip('Save Application')
saveAction.triggered.connect(self.save) # 撤销
undoAction = QAction(QIcon('./images/undo.png'), 'Undo', self)
undoAction.setShortcut('Ctrl+Z')
undoAction.setStatusTip('Undo')
undoAction.triggered.connect(self.textEdit.undo) # 重做
redoAction = QAction(QIcon('./images/redo.png'), 'Redo', self)
redoAction.setShortcut('Ctrl+Y')
redoAction.setStatusTip('Redo')
redoAction.triggered.connect(self.textEdit.redo) # 拷贝
copyAction = QAction(QIcon('./images/copy.png'), 'Copy', self)
copyAction.setShortcut('Ctrl+C')
copyAction.setStatusTip('Copy')
copyAction.triggered.connect(self.copy) # 粘贴
pasteAction = QAction(QIcon('./images/paste.png'), 'Paste', self)
pasteAction.setShortcut('Ctrl+V')
pasteAction.setStatusTip('Paste')
pasteAction.triggered.connect(self.paste) # 剪切
cutAction = QAction(QIcon('./images/cut.png'), 'Cut', self)
cutAction.setShortcut('Ctrl+X')
cutAction.setStatusTip('Cut')
cutAction.triggered.connect(self.cut) # 关于
aboutAction = QAction(QIcon('./images/about.png'), 'About', self)
aboutAction.setStatusTip('About')
aboutAction.triggered.connect(self.about) # 添加菜单
# 对于菜单栏,注意menuBar,menu和action三者之间的关系
# 首先取得QMainWindow自带的menuBar:menubar = self.menuBar()
# 然后在menuBar里添加Menu:fileMenu = menubar.addMenu('&File')
# 最后在Menu里添加Action:fileMenu.addAction(newAction)
menubar = self.menuBar() fileMenu = menubar.addMenu('&File')
fileMenu.addAction(newAction)
fileMenu.addAction(openAction)
fileMenu.addAction(saveAction)
fileMenu.addAction(exitAction) editMenu = menubar.addMenu('&Edit')
editMenu.addAction(undoAction)
editMenu.addAction(redoAction)
editMenu.addAction(cutAction)
editMenu.addAction(copyAction)
editMenu.addAction(pasteAction) helpMenu = menubar.addMenu('&Help')
helpMenu.addAction(aboutAction) # 添加工具栏
# 对于工具栏,同样注意ToolBar和Action之间的关系
# 首先在QMainWindow中添加ToolBar:tb1 = self.addToolBar('File')
# 然后在ToolBar中添加Action:tb1.addAction(newAction)
tb1 = self.addToolBar('File')
tb1.addAction(newAction)
tb1.addAction(openAction)
tb1.addAction(saveAction) tb2 = self.addToolBar('Edit')
tb2.addAction(undoAction)
tb2.addAction(redoAction)
tb2.addAction(cutAction)
tb2.addAction(copyAction)
tb2.addAction(pasteAction) tb3 = self.addToolBar('Exit')
tb3.addAction(exitAction) # 添加状态栏,以显示每个Action的StatusTip信息
self.statusBar() self.setGeometry(0, 0, 600, 600)
self.setWindowTitle('Text Editor')
self.setWindowIcon(QIcon('./images/text.png'))
self.center()
self.show() # 主窗口居中显示
def center(self):
screen = QDesktopWidget().screenGeometry()
size = self.geometry()
self.move((screen.width() - size.width()) / 2, (screen.height() - size.height()) / 2) # 定义Action对应的触发事件,在触发事件中调用self.statusBar()显示提示信息
# 重写closeEvent
def closeEvent(self, event):
reply = QMessageBox.question(self, 'Confirm', \
'Are you sure to quit without saving ?', \
QMessageBox.Yes | QMessageBox.No, \
QMessageBox.No) if reply == QMessageBox.Yes:
self.statusBar().showMessage('Quiting...')
event.accept()
else:
event.ignore()
self.save()
event.accept() # open
def open(self):
self.statusBar().showMessage('Open Text Files')
fname = QFileDialog.getOpenFileName(self, 'Open file', '/home')
self.statusBar().showMessage('Open File')
if fname[0]:
f = open(fname[0], 'r')
with f:
data = f.read()
self.textEdit.setText(data) # save
def save(self):
self.statusBar().showMessage('Add extension to file name')
fname = QFileDialog.getSaveFileName(self, 'Save File')
if (fname[0]):
data = self.textEdit.toPlainText()
f = open(fname[0], 'w')
f.write(data)
f.close() # copy
def copy(self):
cursor = self.textEdit.textCursor()
textSelected = cursor.selectedText()
self.copiedText = textSelected # paste
def paste(self):
self.textEdit.append(self.copiedText) # cut
def cut(self):
cursor = self.textEdit.textCursor()
textSelected = cursor.selectedText()
self.copiedText = textSelected
self.textEdit.cut() # about
def about(self):
url = 'https://en.wikipedia.org/wiki/Text_editor'
self.statusBar().showMessage('Loading url...')
webbrowser.open(url) if __name__ == '__main__':
app = QApplication(sys.argv)
w = TextEditor()
sys.exit(app.exec_())

三 QWidget

QWidget类是所有用户界面对象的基类,所有的窗口和控件都直接或间接继承自QWidget类。QWidget类相关的方法。

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QToolTip
from PyQt5.QtGui import QIcon, QFont if __name__ == '__main__':
app = QApplication(sys.argv) w = QWidget()
btn = QPushButton(w)
btn.setText('Button')
btn.move(20, 20) w.resize(300, 200)
w.move(250, 200)
w.setWindowTitle('QWidget') # setWindowIcon()用于设置应用程序图标
w.setWindowIcon(QIcon('./icon.png')) # setFont()为QToolTip设定字体
QToolTip.setFont(QFont('Monospace Regular', 20))
w.setToolTip('这是一个<b>气泡提示!</b>') w.show() print('QWidget:')
print('w.x() = %d' % w.x())
print('w.y() = %d' % w.y())
print('w.width() = %d' % w.width())
print('w.height() = %d' % w.height()) print('QWidget.geometry')
print('w.geometry().x() = %d' % w.geometry().x())
print('w.geometry().y() = %d' % w.geometry().y())
print('w.geometry().width() = %d' % w.geometry().width())
print('w.geometry().height() = %d' % w.geometry().height()) sys.exit(app.exec_())

脚本输出为:

QWidget:
w.x() = 250
w.y() = 200
w.width() = 300
w.height() = 200
QWidget.geometry
w.geometry().x() = 250
w.geometry().y() = 200
w.geometry().width() = 300
w.geometry().height() = 200

四 QDialog

QDialog的各种子类提供了各种标准对话框,比如QMessageBox, QFileDialog, QInputDialog, QFontDialog等等。它们之间的继承关系如下图所示。

graph TD;
QDialog-->QMessageBox;
QDialog-->QColorDialog;
QDialog-->QFileDialog;
QDialog-->QFontDialog;
QDialog-->QInputDialog;

4.1 QDialog

QDialog类中常用方法:

方法 描述
setWindowTitle() 设置对话框标题
setWindowModality() 设置窗口模态。取值如下:
Qt.NonModal - 非模态
Qt.WindowModal - 窗口模态
Qt.ApplicationModal - 应用程序模态
#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog
from PyQt5.QtCore import Qt class DialogWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('Dialog')
self.resize(350, 300) self.btn = QPushButton(self)
self.btn.setText('弹出对话框')
self.btn.move(50, 50)
self.btn.clicked.connect(self.showDialog) self.show() def showDialog(self):
dialog = QDialog()
btn = QPushButton('ok', dialog)
btn.move(50, 50)
dialog.setWindowTitle('Dialog')
dialog.setWindowModality(Qt.ApplicationModal)
dialog.exec_() if __name__ == '__main__':
app = QApplication(sys.argv)
w = DialogWindow()
sys.exit(app.exec_())

4.2 QMessageBox

QMessageBox是一种通用的弹出式对话框,用于显示消息,允许用户通过单击不同的标准按钮对消息进行反馈。每个标准按钮都有一个预定义的文本、角色和十六进制数。QMessageBox类提供了许多常用的弹出式对话框,比如提示、警告、错误、询问、关于等对话框。这些不同类型的QMessageBox对话框只是显示时得图标不同,其他功能是一样的。QMessageBox类中常用的方法有:

方法 描述
information(QWidget parent, title, text, buttons, defaultButton) parent:父窗口
title:对话框标题
text:对话框文本
buttons:多个标准按钮
defaultButton:默认选中的标准按钮
question(QWidget parent, title, text, buttons, defaultButton) 问答对话框
warning(QWidget parent, title, text, buttons, defaultButton) 警告对话框
critical(QWidget parent, title, text, buttons, defaultButton) 严重错误对话框
about(QWidget parent, title, text) 关于对话框
setTitle() 设置标题
setText() 设置消息正文
setIcon() 设置对话框的图片

QMessageBox中的标准按钮类型有:

类型 描述
QMessageBox.Ok 确定
QMessageBox.Cancel 取消
QMessageBox.Yes
QMessageBox.No
QMessageBox.Abort 终止
QMessageBox.Retry 重试
QMessageBox.Ignore 忽略
#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QApplication, QMessageBox, QWidget, QVBoxLayout, \
QPushButton class MessageBoxWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI() def initUI(self):
vbox = QVBoxLayout()
btn = QPushButton('点击弹出消息框')
btn.clicked.connect(self.showMessageBox)
vbox.addWidget(btn)
self.setLayout(vbox) self.setWindowTitle('QMessageBox')
self.resize(300, 200)
self.show() def showMessageBox(self):
QMessageBox.question(self, '标题', '正文内容', QMessageBox.Yes | \
QMessageBox.No, QMessageBox.Yes)
QMessageBox.warning(self, '标题', '正文内容', QMessageBox.Yes | \
QMessageBox.No, QMessageBox.Yes)
QMessageBox.critical(self, '标题', '正文内容', QMessageBox.Yes | \
QMessageBox.No, QMessageBox.Yes)
QMessageBox.about(self, '标题', '正文内容') if __name__ == '__main__':
app = QApplication(sys.argv)
w = MessageBoxWindow()
sys.exit(app.exec_())







4.3 QInputDialog

QInputDialog控件是一个标准对话框,由一个文本框和两个按钮(OK和Cancel)组成。当用户单击OK按钮后,在父窗口可以接受通过QInputDialog控件输入的信息。在QInputDialog控件中可以输入数字、字符串或者列表中的选择。标签用于提示必要的信息。QInputDialog类常用的方法有:

方法 描述
getInt() 从控件中获取标准整型输入
getDouble() 从控件中获取标准浮点数输入
getText() 从控件中获取标准字符串输入
getItem() 从控件中获取列表里的选项输入
#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QFormLayout, QPushButton, QLineEdit, \
QInputDialog, QApplication class InputDialogWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI() def initUI(self):
layout = QFormLayout() self.btn1 = QPushButton('获得列表里的选项')
self.btn1.clicked.connect(self.getItem)
self.le1 = QLineEdit()
layout.addRow(self.btn1, self.le1) self.btn2 = QPushButton('获得字符串')
self.btn2.clicked.connect(self.getText)
self.le2 = QLineEdit()
layout.addRow(self.btn2, self.le2) self.btn3 = QPushButton('获得整数')
self.btn3.clicked.connect(self.getInt)
self.le3 = QLineEdit()
layout.addRow(self.btn3, self.le3) self.setLayout(layout)
self.setWindowTitle('QInputDialog')
self.show() def getItem(self):
items = ('C', 'C++', 'Java', 'Python')
item, ok = QInputDialog.getItem(self, 'Select Input Dialog', \
'语言列表', items, 0, False)
if ok and item:
self.le1.setText(item) def getText(self):
text, ok = QInputDialog.getText(self, 'Text Input Dialog', \
'输入姓名:')
if ok:
self.le2.setText(str(text)) def getInt(self):
num, ok = QInputDialog.getInt(self, 'Integer Input Dialog', \
'输入数字:')
if ok:
self.le3.setText(str(num)) if __name__ == '__main__':
app = QApplication(sys.argv)
w = InputDialogWindow()
sys.exit(app.exec_())





4.4 QFontDialg

QFontDialog控件是一个常用的字体选择对话框,可以让用户选择显示文本的字体样式、字号大小和格式。

#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QFontDialog, QApplication, \
QPushButton, QLabel class FontDialogWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI() def initUI(self):
layout = QVBoxLayout()
self.btn = QPushButton('选择字体')
self.btn.clicked.connect(self.chooseFont)
self.lb = QLabel('Hello, 测试字体例子')
layout.addWidget(self.btn)
layout.addWidget(self.lb)
self.setLayout(layout)
self.setWindowTitle('FontDialog')
self.show() def chooseFont(self):
font, ok = QFontDialog.getFont()
if ok:
self.lb.setFont(font) if __name__ == '__main__':
app = QApplication(sys.argv)
w = FontDialogWindow()
sys.exit(app.exec_())



4.5 QFileDialog

QFileDialog是用于打开和保存文件的标准对话框。QFileDialog在打开文件时使用了文件过滤器,用于显示指定扩展名的文件。也可以设置使用QFileDialog打开文件时的起始目录和指定扩展名的文件。QFileDialog类的常用方法有:

方法 描述
getOpenFileName() 返回用户所选择文件的名称,并打开该文件
getSaveFileName() 使用用户选择的文件名并保存文件
setFileMode() 可以选择的文件类型,可选枚举常量有:
QFileDialog.AnyFile:任何文件
QFileDialog.ExistingFile:已存在的文件
QFileDialog.Directory:文件目录
QFileDialog.ExistingFiles:已存在的多个文件
setFilter() 设置过滤器,只显示过滤器允许的文件类型
#!/usr/bin/env python3
# -*- coding: utf-8 -*- import sys
from PyQt5.QtWidgets import QWidget, QApplication, QVBoxLayout, QPushButton, \
QLabel, QTextEdit, QFileDialog
from PyQt5.QtCore import QDir
from PyQt5.QtGui import QPixmap class FileDialogWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI() def initUI(self):
layout = QVBoxLayout()
self.btn1 = QPushButton('加载图片')
self.btn1.clicked.connect(self.chooseImage)
self.lb = QLabel()
layout.addWidget(self.btn1)
layout.addWidget(self.lb) self.btn2 = QPushButton('加载文本文件')
self.btn2.clicked.connect(self.chooseTextFile)
self.content = QTextEdit()
layout.addWidget(self.btn2)
layout.addWidget(self.content) self.setLayout(layout)
self.setWindowTitle('FileDialg')
self.show() def chooseImage(self):
fname, _ = QFileDialog.getOpenFileName(self, 'Open file', '/home', \
"Image files (*.jpg *.png *.gif)")
self.lb.setPixmap(QPixmap(fname)) def chooseTextFile(self):
dlg = QFileDialog()
dlg.setFileMode(QFileDialog.AnyFile)
dlg.setFilter(QDir.Files)
if dlg.exec_():
fname = dlg.selectedFiles()
f = open(fname[0], 'r')
with f:
data = f.read()
self.content.setText(data) if __name__ == '__main__':
app = QApplication(sys.argv)
w = FileDialogWindow()
sys.exit(app.exec_())

PyQt5之窗口类型的更多相关文章

  1. Qt学习之路2---窗口组件及窗口类型

    窗口组件: 图形用户界面由不同的窗口和窗口组件构成: Qt以组件对象的方式,构建图形用户界面. 组件的类型包括: ---容器类(父组件):用于包含其他的界面组件 ---功能类(子组件):用于实现特定的 ...

  2. html5-6 Frame框架窗口类型

    html5-6  Frame框架窗口类型 一.总结 一句话总结: 1.点左侧的a链接如何打开右侧页面? <a href='user/index.html' target='right'>& ...

  3. QObject提供了QMetaObject元类信息(相当于RTTI和反射),信号与连接,父子关系,调试信息,属性,事件,继承关系,窗口类型,线程属性,时间器,对象名称,国际化

    元类信息(相当于RTTI和反射),信号与连接,父子关系,调试信息,属性,事件,继承关系,窗口类型,线程属性,时间器,对象名称,国际化其中元类又提供了:classInfo,className,构造函数, ...

  4. WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口

    原文:WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口 当我们对 Window 类型写一个附加属性的时候,在属性变更通知中我们需要判断依赖对象是否是一个窗口.但是,如果直接判断是否是 W ...

  5. wxWidgets窗口类型

    如果在创建窗口的时候你没有指定窗口的边框类型,那么在不同的平台上将会有不同的边框类型的缺省值.在windows平台上,控件边框的缺省值为 wxSUNKEN_BORDER,意为使用当前系统风格的边框.你 ...

  6. pyqt5实现窗口跳转并关闭上一个窗口

    关键在于要定义一个关闭窗体的函数colsewin() 然后将按键与该函数连接(connect)在一起即可 import sys from PyQt5.QtWidgets import QMainWin ...

  7. pyqt5 设置窗口按钮等可用与不可用

    setEnabled(True) 设置窗口或者按钮可用,Flase不可用

  8. 窗口类型(Widget, Window, Dialog, Desktop, SubWindow等等)

    http://doc.qt.io/qt-5/qwidget.html#windowFlags-prop http://doc.qt.io/qt-5/qtwidgets-widgets-windowfl ...

  9. 解决qt5窗口不刷新(测试窗口类型,测试窗口属性)

    QApplication::notify #if QT_VERSION >= 0x050000        if (QEvent::Show == pEvent->type())     ...

随机推荐

  1. 爬虫系列---scrapy post请求、框架组件和下载中间件+boss直聘爬取

    一 Post 请求 在爬虫文件中重写父类的start_requests(self)方法 父类方法源码(Request): def start_requests(self): for url in se ...

  2. .NET平台下,初步认识AutoMapper

    初步认识AutoMapper AutoMapper 初步认识AutoMapper 前言 手动映射 使用AutoMapper 创建映射 Conventions 映射到一个已存在的实例对象   前言 通常 ...

  3. day 13 迭代器、可迭代对象、迭代器对象、生成器、生成器对象、枚举对象

    迭代器大概念 # 迭代器:循环反馈的容器(集合类型)# -- 不同于索引取值,但也可以循环的从容器对象中从前往后逐个返回内部的值​# 优点:不依赖索引,完成取值# 缺点:不能计算长度,不能指定位取值( ...

  4. 基于vue-simple-uploader封装文件分片上传、秒传及断点续传的全局上传插件

    目录 1. 前言 2. 关于vue-simple-uploader 3. 基于vue-simple-uploader封装全局上传组件 4. 文件上传流程概览 5. 文件分片 6. MD5的计算过程 7 ...

  5. Ubuntu下解压压缩文件

    1.ZIP解压    ZIP因为它的跨平台使用优点,是目前使用率最高的一种压缩方式,但是它的压缩率相比较tar.gz和tar.gz2来讲,却要低很多.    压缩命令:zip -r archive_n ...

  6. Kubernetes — 深入解析Pod对象:基本概念(一)

    在上一篇文章中,我详细介绍了 Pod 这个 Kubernetes 项目中最重要的概念. 现在,你已经非常清楚:Pod,而不是容器,才是 Kubernetes 项目中的最小编排单位.将这个设计落实到 A ...

  7. python 支付宝SDK

    python 支付宝SDK代码如下 from datetime import datetime from Crypto.PublicKey import RSA from Crypto.Signatu ...

  8. tomcat发请求,查看各个环节的耗时时间

    从一台机器给另一台机器tomcat发请求,查看各个环节的耗时时间 - 业精于勤,荒于嬉:行成于思,毁于随. - CSDN博客https://blog.csdn.net/YAOQINGGG/articl ...

  9. mysql多表多字段查询并去重

    mysql多表多字段查询并去重 - MySQL-ChinaUnix.nethttp://bbs.chinaunix.net/forum.php?mod=viewthread&tid=42549 ...

  10. php提供的用户密码加密函数

    在实际项目中,对用户的密码加密基本上采用的  md5加盐的方式, php5.5后提供了一个加密函数,不需要手动加盐,不需要去维护盐值, $str = "123456"; $pwd ...