PyQt5之窗口类型
注:原创不易,转载请务必注明原作者和出处,感谢支持!
一 写在开头
1.1 本文内容
本文的主要内容:PyQt中的窗口部件:QMainWindow,QWidget,QDialog。
上述三种窗口部件都是用来创建窗口的,可以直接使用,也可以继承后再使用。它们的异同如下:
- QMainWindow窗口可以包含菜单栏、工具栏、状态栏、标题栏等,是最常见的窗口形式,是GUI程序的主窗口。
- QDialog是对话框窗口的基类。对话框主要用来执行短期任务,或者与用户进行互动,它可以是模态的,也可是非模态的。QDialog窗口没有菜单栏、工具栏、状态栏等。
- QWidget即可以用来作为顶层窗口(QMainWindow),可以嵌入到其他窗口中。
三者之间的继承关系如下图:
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等等。它们之间的继承关系如下图所示。
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之窗口类型的更多相关文章
- Qt学习之路2---窗口组件及窗口类型
窗口组件: 图形用户界面由不同的窗口和窗口组件构成: Qt以组件对象的方式,构建图形用户界面. 组件的类型包括: ---容器类(父组件):用于包含其他的界面组件 ---功能类(子组件):用于实现特定的 ...
- html5-6 Frame框架窗口类型
html5-6 Frame框架窗口类型 一.总结 一句话总结: 1.点左侧的a链接如何打开右侧页面? <a href='user/index.html' target='right'>& ...
- QObject提供了QMetaObject元类信息(相当于RTTI和反射),信号与连接,父子关系,调试信息,属性,事件,继承关系,窗口类型,线程属性,时间器,对象名称,国际化
元类信息(相当于RTTI和反射),信号与连接,父子关系,调试信息,属性,事件,继承关系,窗口类型,线程属性,时间器,对象名称,国际化其中元类又提供了:classInfo,className,构造函数, ...
- WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口
原文:WPF 判断一个对象是否是设计时的窗口类型,而不是运行时的窗口 当我们对 Window 类型写一个附加属性的时候,在属性变更通知中我们需要判断依赖对象是否是一个窗口.但是,如果直接判断是否是 W ...
- wxWidgets窗口类型
如果在创建窗口的时候你没有指定窗口的边框类型,那么在不同的平台上将会有不同的边框类型的缺省值.在windows平台上,控件边框的缺省值为 wxSUNKEN_BORDER,意为使用当前系统风格的边框.你 ...
- pyqt5实现窗口跳转并关闭上一个窗口
关键在于要定义一个关闭窗体的函数colsewin() 然后将按键与该函数连接(connect)在一起即可 import sys from PyQt5.QtWidgets import QMainWin ...
- pyqt5 设置窗口按钮等可用与不可用
setEnabled(True) 设置窗口或者按钮可用,Flase不可用
- 窗口类型(Widget, Window, Dialog, Desktop, SubWindow等等)
http://doc.qt.io/qt-5/qwidget.html#windowFlags-prop http://doc.qt.io/qt-5/qtwidgets-widgets-windowfl ...
- 解决qt5窗口不刷新(测试窗口类型,测试窗口属性)
QApplication::notify #if QT_VERSION >= 0x050000 if (QEvent::Show == pEvent->type()) ...
随机推荐
- C# -- 使用委托 delegate 执行异步操作
C# -- 使用委托 delegate 执行异步操作 委托是一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似. 与 C 中的函数指针不同,委托是面向对象的.类型安全的和保险的. 委托的 ...
- Redis管道和发布订阅
管道:原子性执行命令 ''' redis-py默认在执行每次请求都会创建(连接池申请连接)和断开(归还连接池)一次连接操作, 如果想要在一次请求中指定多个命令,则可以使用pipline实现一次请求指定 ...
- PHP跨域jsonp方式
<?php header('Access-Control-Allow-Origin:*');//注意!跨域要加这个头 上面那个没有 $arr = array ('a'=>1,'b'=> ...
- Vue-Router模式、钩子
转:https://www.cnblogs.com/heioray/p/7193841.html 模式 vue-router中的模式选项主要在router实例化的时候进行定义的,如下 const ro ...
- Unknown column 'user_uid' in 'field list' sql错误解决过程
在idea中运行一直有错,找了好多个地方都找不到,以为是我的字段名字写错了,然而都是对的. 把错误的这个字段删了再打一遍就好了,
- idea右键无法新建Java Class
项目中新建目录之后,要在该目录下新增java Class文件,右键——>New发现无对应选项. 原因:新建目录之后需要设置目录作用,从而让idea识别. 方法:File-Project Stru ...
- 四 Struts2 反射实现
package com.myreflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import ...
- eclipse下将maven项目打包为jar(1.不带第三方jar,2.带第三方jar)
由于项目需要讲maven项目打包为jar包,由于之前没类似经验,百度找例子走了不少弯路,这边随手记录下,网上说的 开发工具:eclipse jar包管理:maven 一般打包出来的jar包分为两种 一 ...
- python之log
#!/usr/bin/python # -*- coding: UTF- -*- ''' ''' import logging # 设置输出文件.文件格式和日志级别 logging.basicConf ...
- Stream02
import 'package:flutter/material.dart';import 'dart:async';import 'dart:math'; void main()=>runAp ...