200字范文,内容丰富有趣,生活中的好帮手!
200字范文 > Python3 PyQt5 窗口(国际化/QMainWindow/QWidget/QDialog)

Python3 PyQt5 窗口(国际化/QMainWindow/QWidget/QDialog)

时间:2019-08-05 23:10:31

相关推荐

Python3 PyQt5 窗口(国际化/QMainWindow/QWidget/QDialog)

Python3 PyQt5 窗口(国际化/QMainWindow/QWidget/QDialog)

本文由 Luzhuo 编写,转发请保留该信息.

原文:/Rozol/article/details/87904498

PyQt5基本介绍见: PyQt5 Qt Designer (Qt设计师)

简介

窗口主要分为:QMainWindow(主窗口) / QWidget(基本窗口) / QDialog(对话框)这三种.

QWidget: 最基本的窗口QMainWindow: 在 QWidget 的基础上多了 菜单栏 / 工具栏 / 状态栏 / 标题栏 等QDialog: 对话框窗口

使用的话:

1.如果是主窗口, 需要菜单栏之类的, 就用QMainWindow.

2.如果是对话框, 就用QDialog.

3.其他不确定的窗口, 都可以用QWidget.

文本国际化

这里先讲下文本国际化, 如果不进行国际化, 那么你运行之后, 发现控件都是英文的.

自带的国际化

PyQt5自带的翻译文件在C:\Code\Python_Vir\python1\Lib\site-packages\PyQt5\Qt\\translations\目录下,不过翻译并不完全, 由于已经被编译成.qm文件, 你也改不了它.

from PyQt5.Qt import QTranslator, QLocale, QLibraryInfotranslator = QTranslator(app)if translator.load("qt_" + QLocale.system().name(), QLibraryInfo.location(QLibraryInfo.TranslationsPath)):app.installTranslator(translator)

效果:

自定义的国际化

编写文本时, 有原来的"content"变成现在的self.tr("content"), 其他除了要先加载翻译者之外, 均不变.

def initUI(self):# 加载翻译文件translator = QTranslator(app)if translator.load('qt_zh_CN'):app.installTranslator(translator)btn = QPushButton(self.tr("Color"), self)btn.clicked.connect(self.click)self.setGeometry(300, 300, 550, 350)self.setWindowTitle('Dialog')self.show()btn = QPushButton(self.tr("Color"), self)btn.clicked.connect(self.click)def click(self):QColorDialog.getColor()

1.生成.ts文件

# 创建.ts文件, 存在则更新pylupdate5 international.py -ts qt_zh_CN.ts

2.打开Linguist进行手动翻译, 翻译完点保存

linguist qt_zh_CN.ts

3.生成.qm文件

lrelease qt_zh_CN.ts

效果:

自己写的是实现了国际化, 原生的英文界面你也拿它没辙.

另外翻译出现问题可以通过修改.ts来修正.

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE TS><TS version="2.1" language="zh_CN"><context><name>Widget</name><message><location filename="international.py" line="24"/><source>Color</source><translatorcomment>颜色</translatorcomment><translation>颜色</translation></message></context></TS>

比如代码位置变了, 会给你打个过时的标签, 如

<translation type="obsolete">取消</translation>

这时只需要把type="obsolete"删掉, 然后把line="24"改成正确的行就行了.

另外, 其实翻译只需要<translation>颜色</translation>标签就够了,<translatorcomment>颜色</translatorcomment>可有可无.

自带的国际化 + 自定义的国际化

只需要同时加载两个翻译者就好了.

def initUI(self):# 加载翻译文件translator_sys = QTranslator(app)translator_my = QTranslator(app)if translator_sys.load("qt_" + QLocale.system().name(), QLibraryInfo.location(QLibraryInfo.TranslationsPath)) and translator_my.load('qt_zh_CN'):app.installTranslator(translator_sys)app.installTranslator(translator_my)btn = QPushButton(self.tr("Color"), self)btn.clicked.connect(self.click)self.setGeometry(300, 300, 550, 350)self.setWindowTitle('Dialog')self.show()def click(self):QColorDialog.getColor()

效果:

如果需要切换语言

app.removeTranslator(translator_my)app.installTranslator(translator_sys)

注: 为了敲代码效率, 我的所有案例代码都不会用self.tr("xxx")这种方式来写, 而是直接写"xxx", 包括这篇文章的以下代码.

QMainWindow 主窗口

QMainWindow 是一个顶层窗口(没有父窗口), 包含了 MenuBar(菜单栏) / ToolBars(工具栏) / Dock Widgets(停靠控件区) / Status Bar(状态栏), 中心窗口区被一个 QWidget 占着, 可通过setCentralWidget()来设置(不能通过 setLayout() 设置).

创建主窗口

我们有两种方式创建, 第一种是创建对象, 第二种是继承类, 一般我们会采用第二种, 包括博客文章的案例代码采用这种方式.

第一种: 创建对象方式

#!/usr/bin/env python# coding=utf-8__author__ = 'Luzhuo'__date__ = '/2/19'# QMainWindow 创建主窗口import sysfrom PyQt5.QtWidgets import QApplication, QMainWindowfrom PyQt5.QtGui import QIcondef mainwindow1():'''方式一: 通过创建对象方式创建主窗口'''# 每个PyQt5应用都要创建一个应用对象 (sys.argv是一组命令行参数列表)app = QApplication(sys.argv)# 主窗口w = QMainWindow()w.setGeometry(300, 300, 550, 350)w.setWindowTitle('我是窗口标题')w.setWindowIcon(QIcon('icon.png')) # 设置图标w.show() # 展示该控件# 退出主程序sys.exit(app.exec_())if __name__ == '__main__':mainwindow1()

第二种: 继承类方式

class MainWindow(QMainWindow):'''方式二: 通过继承类方式创建主窗口'''def __init__(self):super().__init__()self.initUI()def initUI(self):self.setGeometry(300, 300, 550, 350)self.setWindowTitle('我是窗口标题')self.setWindowIcon(QIcon('icon.png')) # 设置图标self.show() # 展示该控件if __name__ == '__main__':app = QApplication(sys.argv)ex = MainWindow()sys.exit(app.exec_())

效果:

窗口位置与大小

我们有三种方式设置窗口的位置与大小:

第一种:

self.resize(550, 350) # 改变窗口大小(px)self.move(300, 300) # 移动控件位置(px)

第二种 (是第一种两方法的结合):

self.setGeometry(300, 300, 550, 350) # 放在屏幕上并设置大小

第三种 (居中显示):

qr = self.frameGeometry() # 得到应用主窗体大小cp = QDesktopWidget().availableGeometry().center() # QDesktopWidget 得到桌面大小, availableGeometry 得到屏幕分辨率, center 得到中间点坐标qr.moveCenter(cp) # 将 应用中间点 移到 屏幕中间点self.resize(550, 350)self.move(qr.topLeft()) # 将 应用左上标 设为 矩形左上标

窗口的几何结构:

窗口分为 不含外边框的几何结构 和 含外边框的几何结构.

# --- 无边框几何结构 ---# 修改客户区的大小(鼠标可修改)self.resize(550, 350)self.resize(QSize(550, 350))self.setGeometry(300, 300, 550, 350)self.setGeometry(QRect(300, 300, 550, 350))# 修改客户区的大小(鼠标不可修改)self.setFixedWidth(550) # 宽度固定 (高度可变)self.setFixedHeight(350) # 高度固定self.setFixedSize(550, 350) # 宽度与高度都固定self.setFixedSize(QSize(550, 350))# 获取客户区大小qsize = self.size()qrect = self.geometry()width = self.width()height = self.height()print("QSize - width:{w} height:{h}".format(w=qsize.width(), h=qsize.height()))print("QRect - x:{x} y:{y} width:{w} height:{h}".format(x=qrect.x(), y=qrect.y(), w=qrect.width(), h=qrect.height()))print("width:{w} height:{h}".format(w=width, h=height))# --- 有边框几何结构 ---# 设置窗口位置self.move(300, 300)self.move(QPoint(300, 300))# 获取窗口位置与大小qrect = self.frameGeometry() # 位置和大小qpoint = self.pos() # 左上角坐标print("QRect - x:{x} y:{y} width:{w} height:{h}".format(x=qrect.x(), y=qrect.y(), w=qrect.width(), h=qrect.height()))print("QRect - x:{x} y:{y}".format(x=qpoint.x(), y=qpoint.y()))

关闭窗口

关闭窗口, 除了点击右上角的红×退出外, 还有自己写退出的逻辑(与退出槽连接).

退出应用的信号槽连接:

qbtn.clicked.connect(QCoreApplication.instance().quit)

完整代码:

import sysfrom PyQt5.QtWidgets import QApplication, QMainWindow, QPushButtonfrom PyQt5.QtCore import QCoreApplicationclass MainWindow(QMainWindow):'''退出窗口'''def __init__(self):super().__init__()self.initUI()def initUI(self):qbtn = QPushButton('Quit', self)qbtn.resize(qbtn.sizeHint())qbtn.move(50, 50)# 按钮的点击信号 与 应用退出槽 进行连接qbtn.clicked.connect(QCoreApplication.instance().quit)self.setGeometry(300, 300, 550, 350)self.setWindowTitle('窗口的关闭')self.show()if __name__ == '__main__':app = QApplication(sys.argv)ex = MainWindow()sys.exit(app.exec_())

应用退出事件:

如果你想在应用退出时做点操作, 比如弹出个对话框之类的. 那么就需要重写def closeEvent(self, event):方法

def closeEvent(self, event):if True:event.accept() # 执行事件else:event.ignore() # 忽略事件

MenuBar 菜单栏

菜单栏由 菜单栏 / 菜单 / 子菜单 / 动作 组成.

创建动作:

jumpAct = QAction(QIcon('icon.png'), '&Jump to Source', self) # 图标 / exit标签jumpAct.setShortcut('F4') # 快捷键jumpAct.setStatusTip('这是 Jump to Source 的提示信息') # 状态栏提示信息jumpAct.triggered.connect(qApp.quit) # 触发 quit 事件

创建子菜单:

impMenu = QMenu('Tool Windows', self)impMenu.addAction(strucAct) # 往子菜单添加一个动作

创建菜单:

viewMenu = menubar.addMenu('&View') # 添加View菜单viewMenu.addMenu(impMenu) # 添加子菜单viewMenu.addSeparator() # 添加分隔线viewMenu.addAction(jumpAct) # 添加 动作

创建菜单栏:

menubar = self.menuBar()

完整代码:

import sysfrom PyQt5.QtWidgets import QApplication, QMainWindow, QAction, qApp, QMenufrom PyQt5.QtGui import QIconclass MainWindow(QMainWindow):'''菜单栏'''def __init__(self):super().__init__()self.initUI()def initUI(self):# 创建动作jumpAct = QAction(QIcon('icon.png'), '&Jump to Source', self) # 图标 / exit标签jumpAct.setShortcut('F4') # 快捷键jumpAct.setStatusTip('这是 Jump to Source 的提示信息') # 状态栏提示信息jumpAct.triggered.connect(qApp.quit) # 触发 quit 事件strucAct = QAction(QIcon('icon.png'), '&Structure', self)strucAct.setShortcut("Alt+7")# 创建子菜单impMenu = QMenu('Tool Windows', self)impMenu.addAction(strucAct) # 往子菜单添加一个动作# 创建菜单栏menubar = self.menuBar()# 创建菜单viewMenu = menubar.addMenu('&View') # 添加View菜单viewMenu.addMenu(impMenu) # 添加子菜单viewMenu.addSeparator() # 添加分隔线viewMenu.addAction(jumpAct) # 添加 动作self.setGeometry(300, 300, 550, 350)self.setWindowTitle('菜单栏')self.show()if __name__ == '__main__':app = QApplication(sys.argv)ex = MainWindow()sys.exit(app.exec_())

效果:

勾选动作:

当然, 菜单里的动作除了上述比较常见的外, 还有一种动作, 叫勾选动作

statusbarAct = QAction('View statusbar', self, checkable=True)statusbarAct.setStatusTip('View statusbar')statusbarAct.setChecked(True) # True为默认选中状态statusbarAct.triggered.connect(self.toggleMenu)

效果:

右键上下菜单:

菜单除了出现在菜单栏, 它还有一种形式, 就是我们采用的右键菜单.

有实现右键菜单, 就要重写 上下文菜单事件 (def contextMenuEvent(self, event):)

1.创建子菜单, 并添加动作

cmenu = QMenu(self)quitAct = cmenu.addAction("Quit")

2.获取用户选择的动作, 然后就动作进行判断是哪个动作

action = cmenu.exec_(self.mapToGlobal(event.pos())) # mapToGlobal 将组件相对坐标转为窗口绝对坐标, exec_ 显示菜单# 如果触发的动作为 quitAct 则退出应用if action == quitAct:qApp.quit()

完整代码

def contextMenuEvent(self, event):'''右键上下文菜单'''# 创建子菜单, 并添加动作cmenu = QMenu(self)newAct = cmenu.addAction("New")opnAct = cmenu.addAction("Open")quitAct = cmenu.addAction("Quit")action = cmenu.exec_(self.mapToGlobal(event.pos())) # mapToGlobal 将组件相对坐标转为窗口绝对坐标, exec_ 显示菜单# 如果触发的动作为 quitAct 则退出应用if action == quitAct:qApp.quit()

效果:

ToolBars 工具栏

工具栏主要是为了方便用户使用而存在的, 其功能都应该能够在菜单栏找到(大学设计书上是这么说的, 不过菜单栏没这功能又能把我咋地 _)

创建一个动作

# 创建一个动作exitAct = QAction(QIcon('icon.png'), 'Exit', self)exitAct.setShortcut('Ctrl+Q')exitAct.triggered.connect(qApp.quit)

把这个动作添加到工具栏

# 将(Exit)动作添加到工具栏self.toolbar = self.addToolBar('Exit') # 添加Exit工具栏self.toolbar.addAction(exitAct)

效果

添加控件:

ToolBar除了能添加动作外, 还能添加任意控件.

lineEdit = QLineEdit()self.toolbar.addSeparator() # 分隔线self.toolbar.addWidget(lineEdit)

Dock Widgets 停靠控件区

停靠空间区的布局嵌套是有QDockWidget来完成的.

需要创建一个Widget设置到DockWidget上.

1.创建Widget

w = QWidget()

2.创建DockWidget

dock = QDockWidget("窗口1")dock.setWidget(w) # 为 dockwidget 设置 widgetdock.setFeatures(dock.DockWidgetFloatable | dock.DockWidgetMovable) # 设置特征(DockWidgetFeature)self.addDockWidget(Qt.LeftDockWidgetArea, dock) # 添加 dockwidget 到主窗口

效果:

嵌套布局:

当你添加多个 DockWidget 到主窗口时, 你会发现这些窗口只能往左右放, 若要实现往两 DockWidget 中间放, 则要开启嵌套.

self.setDockNestingEnabled(True)

排列组合:

若要将这些小窗口按水平(或垂直 或水平+垂直)排列, 将其水平分隔成同样的宽度.

self.splitDockWidget(win1Dock, win2Dock, Qt.Horizontal)self.splitDockWidget(win2Dock, win3Dock, Qt.Horizontal)self.splitDockWidget(win1Dock, win4Dock, Qt.Vertical)

tab页:

多个窗口合成一个窗口, 窗口通过tab标签切换.

self.tabifyDockWidget(win1Dock, win2Dock)

综合代码

def getDock(self, name):w = QWidget()dock = QDockWidget(name)dock.setWidget(w)dock.setFeatures(dock.DockWidgetFloatable | dock.DockWidgetMovable)return dockdef initUI(self):win1Dock = self.getDock("win1")win2Dock = self.getDock("win2")win3Dock = self.getDock("win3")win4Dock = self.getDock("win4")self.addDockWidget(Qt.LeftDockWidgetArea, win1Dock)self.addDockWidget(Qt.RightDockWidgetArea, win2Dock)self.addDockWidget(Qt.BottomDockWidgetArea, win3Dock)self.addDockWidget(Qt.BottomDockWidgetArea, win4Dock)# 实现任意嵌套self.setDockNestingEnabled(True)# 实现分隔 (可水平 / 垂直 / 垂直+水平 从而实现任意效果)self.splitDockWidget(win1Dock, win2Dock, Qt.Horizontal)self.splitDockWidget(win2Dock, win3Dock, Qt.Horizontal)self.splitDockWidget(win1Dock, win4Dock, Qt.Vertical)# tab页self.tabifyDockWidget(win1Dock, win2Dock)

综合效果

QtWidgets.QDockWidget.DockWidgetFeature

QtCore.Qt.DockWidgetArea

Status Bar 状态栏

状态栏一般显示一些提示信息, 可以是临时的, 也可以是永久的.

一般在 状态栏的左侧 显示 实时信息, 而在其右侧显示 永久信息.

显示实时信息:

self.statusbar = self.statusBar()self.statusbar.showMessage('这是状态栏信息')self.statusbar.showMessage('这是状态栏信息', 5 * 1000) # 提示5s消失

添加控件:

label1 = QLabel("This is a Label")label2 = QLabel("CopyRight @ Luzhuo.me ")# addWidget 在左侧添加临时控件self.statusbar.addWidget(label1)# addWidget 在右侧添加永久控件self.statusbar.addPermanentWidget(label2)

效果:

QWidget 基本窗口

QWidget 是所有用户界面对象的基类. 准确的说它并不属于窗口类型, 而是属于控件类型.

注: 只有Slots的表格, 注释与实际执行一致; 有Func & Slots的表格, ()内为Slots的执行效果, 没有()的为两者实际执行一致

窗口:

方法:

bool_isW = self.isWindow() # 是否为独立窗口widget = self.window() # 当前部件所在的独立窗口widget_parent = self.parentWidget() # 得到父窗口

窗口样式:

默认窗口样式 是使用 当前操作系统的原生窗口样式, 在不同的操作系统下原生窗口样式显示的效果不一样.

我们可以定制窗口样式.

窗口类型 (|组合):

窗口外观标志:

自定义窗口:

其他高大上的标志:

self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.MSWindowsFixedSizeDialogHint | Qt.Dialog)

窗口风格:

方法:

list_style = QStyleFactory.keys() # 当前平台支持的 QStyle 窗口风格样式self.setStyle(QStyleFactory.create(list_style[1])) # 设置窗口风格QApplication.setStyle(QStyleFactory.create("WindowsXP")) # 给 App 设置窗口风格, 其他Widget默认(无设置)使用App的风格

窗口最大化:

上面4个既是函数, 又是槽

self.showMaximized() # 是函数, 也是槽

窗口的最大化, 还有这种方式可以调用

self.setWindowState(Qt.WindowMaximized)

方法:

windowStates = self.windowState() # 获取状态ismin = self.isMinimized() # 判断窗口是否为最小化ismax = self.isMaximized() # 判断窗口是否为最大化isfull = self.isFullScreen() # 判断窗口是否为全屏

禁用窗口:

禁用该窗口, 会使该窗口里所有控件处于不能被使用状态.

没错, 这是一个槽

上面2个方法既是函数, 也是槽, 但是效果缺是相反的, 尴尬…

self.setDisabled(True) # 启用该窗口 (与槽效果相反)

方法:

isenable = self.isEnabled() # 该窗口是否启用isaction = self.isActiveWindow() # 判断该窗口是否激活self.activateWindow() # 设置窗口为激活状态

窗口的可见

self.setVisible(True) # 设置可见 (与槽效果相反)

方法:

isVisible = self.isVisible() # 窗口是否可见isHidden = self.isHidden() # 窗口是否隐藏self.setVisible(True) # 设置可见self.setHidden(True) # 设置隐藏

还有几个可以复写的事件:

def closeEvent(self, QCloseEvent):'''关闭'''passdef showEvent(self, QShowEvent):'''显示'''passdef hideEvent(self, QHideEvent):'''隐藏'''passdef mouseMoveEvent(self, QMouseEvent):'''移动'''point_old = QMouseEvent.oldPos() # 旧坐标point_new = QMouseEvent.newPos() # 新坐标def resizeEvent(self, QResizeEvent):'''大小改变'''size_old = QResizeEvent.oldSize() # 旧大小size_new = QResizeEvent.newSize() # 新大小

焦点:

self.setFocus() # 使窗口获得焦点

方法

hashFocus = self.hasFocus() # 判断窗口是否获得焦点self.clearFocus() # 使窗口失去焦点widget = self.focusWidget() # 得到窗口内获得焦点的子窗口

他还有两个可以复写的方法

def focusInEvent(self, QFocusEvent):'''获得焦点'''passdef focusOutEvent(self, QFocusEvent):'''失去焦点'''pass

鼠标与键盘:

方法:

self.grabKeyboard() # 捕获键盘事件self.releaseKeyboard() # 释放键盘事件self.grabMouse() # 捕获鼠标事件self.releaseMouse() # 释放鼠标事件widget = self.keyboardGrabber() # 得到正在捕获键盘事件的窗口widget = self.mouseGrabber() # 得到正在捕获鼠标事件的窗口

几个可复写的键盘事件

def keyPressEvent(self, QKeyEvent):'''键盘按下'''int_key = QKeyEvent.key() # 得到键值if int_key == Qt.Key_Escape:passdef keyReleaseEvent(self, QKeyEvent):'''键盘松开'''pass

几个可复写的鼠标事件:

def mousePressEvent(self, QMouseEvent):'''鼠标按下'''passpoint = QMouseEvent.pos() # 鼠标(相对)坐标int_x = QMouseEvent.x() # 鼠标(相对)x坐标int_y = QMouseEvent.y() # 鼠标(相对)y坐标point_g = QMouseEvent.globalPos() # 鼠标(全局)坐标int_gx = QMouseEvent.globalX() # 鼠标(全局)x坐标int_gy = QMouseEvent.globalY() # 鼠标(全局)y坐标mouseButton = QMouseEvent.button() # 引起事件的鼠标键mouseButtons = QMouseEvent.buttons() # 事件发生时的鼠标键状态 (|组合)'''Qt.MouseButton 的枚举 | Description--- | ---Qt.NoButton | 无键Qt.LeftButton | 左键Qt.RightButton | 右键Qt.MidButton | 中键'''if mouseButton == Qt.LeftButton:passdef mouseReleaseEvent(self, QMouseEvent):'''鼠标松开'''passdef mouseDoubleClickEvent(self, QMouseEvent):'''鼠标双击'''passdef mouseMoveEvent(self, QMouseEvent):'''鼠标移动 (默认需要按下)# 开启鼠标追踪(不需要按下)self.setMouseTracking(True)'''mouseButton = QMouseEvent.button() # Move事件 总是返回 Qt.NoButtondef enterEvent(self, QEvent):'''鼠标进入窗体'''passdef leaveEvent(self, QEvent):'''鼠标离开窗体'''passdef wheelEvent(self, QWheelEvent):'''鼠标滚轮滚动'''int_delta = QWheelEvent.delta() # 滚轮转动的角度orientation = QWheelEvent.orientationI() # 滚轮转动的方向'''Qt.Orientation 的枚举 | Description--- | ---Qt.Horizontal | 横向Qt.Vertical | 纵向'''if orientation == Qt.Horizontal:pass

上述的鼠标移动事件只有按下时才追踪, 如果想不按下就追踪, 则要加上下面这段代码

# 开启鼠标追踪(不需要按下)self.setMouseTracking(True)

布局:

方法

self.setLayout(QLayout()) # 设置顶级布局layout = self.layout() # 获得顶级布局

字体:

方法

self.setFont(QFont()) # 设置字体font = self.font() # 获得字体

关于事件的处理:

def enterEvent(self, QEvent):# 事件的处理if True:QEvent.accept() # 接受事件else:QEvent.ignore() # 忽略事件# 事件被忽略后: 关闭事件 - 窗口将不会被关闭; 键盘、鼠标等输入事件 - 向上传播到父窗口pass

QToolTip 提示泡泡

设置泡泡字体

QToolTip.setFont(QFont('SansSerif', 10))

在需要提示的Widget上使用

self.setToolTip('This is a <b>QWidget</b> widget')

案例: 在Widget 和 PushButton 上添加提示泡泡

def initUI(self):# 设置字体QToolTip.setFont(QFont('SansSerif', 10))self.setToolTip('This is a <b>QWidget</b> widget')btn = QPushButton('Button', self)btn.setToolTip('This is a <b>QPushButton</b> widget')btn.resize(btn.sizeHint()) # sizeHint 为默认大小btn.move(50, 50)

效果:

QDialog 对话框

QDialog中还有几个与打印相关的对话框(QAbstractPrintDialog / QPageSetupDialog / QPrintDialog / QPrintPreviewDialog)全部放到打印里讲

QDialog

该Dialog是可以自己放控件来设计它的样子和作用, 当然系统也内置很多设计好的Dialog, 如: QColorDialog / QFileDialog / QMessageBox 等等.

案例

import sysfrom PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QDialogfrom PyQt5.Qt import Qtclass MyDialog(QDialog):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setWindowTitle("My Dialog")self.resize(200, 100)self.btn = QPushButton("ok", self)self.btn.clicked.connect(self.close)'''Qt.WindowModality | Description--- | ---Qt.NonModal | 非模态, 可与其他窗口交互Qt.WindowModal | 窗口模态, 未处理完当前对话框, 将阻止与对话框父窗口交互Qt.ApplicationModal | 应用程序模态, 阻止和任何其他窗口交互'''self.setWindowModality(Qt.ApplicationModal)# self.exec_()def text(self):return self.btn.text()@staticmethoddef getText():dialog = MyDialog()dialog.exec_()text = dialog.text()return text

使用的话也很简单:

text = MyDialog.getText()print(text)

QMessageBox 消息盒子

消息盒子主要弹出: 提示 / 警告 / 错误 / 询问 / 关于 等等对话框, 不过仅仅是体现在显示的图标不同

主要方法:

主要方法:msgBox.setWindowTitle("默认1") # 设置标题msgBox.setText("The document has been modified.") # 主文本msgBox.setInformativeText("Do you want to save your changes?") # 副文本msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) # 按钮smsgBox.setDefaultButton(QMessageBox.Save) # 默认(选中)按钮msgBox.setDetailedText("If the detailed text property is set...") # 详情按钮msgBox.setIcon(QMessageBox.Question) # 图标msgBox.setIconPixmap(QPixmap('icon.png'))ret = msgBox.exec_()# 上述的综合体ret = QMessageBox.question(self, 'Question', "The document has been modified...", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

分别设置:

# 默认1msgBox = QMessageBox()msgBox.setWindowTitle("默认1")msgBox.setText("The document has been modified.")msgBox.exec_()# 默认2 (+按钮)msgBox = QMessageBox()msgBox.setWindowTitle("默认2")msgBox.setText("The document has been modified.") # 主文本msgBox.setInformativeText("Do you want to save your changes?") # 副文本msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel) # 按钮smsgBox.setDefaultButton(QMessageBox.Save) # 默认(选中)按钮ret = msgBox.exec_()if ret == QMessageBox.Save:passelif ret == QMessageBox.Discard:passelif ret == QMessageBox.Cancel:passelse:pass# 默认3 (+DetailedText)msgBox = QMessageBox()msgBox.setWindowTitle("默认3")msgBox.setText("The document has been modified.")# 增加详情按钮msgBox.setDetailedText("If the detailed text property is set, the Show Details… button will be shown.")msgBox.exec_()# 默认4 (+icon)msgBox = QMessageBox()msgBox.setWindowTitle("默认4")msgBox.setText("The document has been modified.")msgBox.setIcon(QMessageBox.Question)msgBox.exec_()

效果:

综合体:

对话框类型与图标

支持的带类型的对话框, 除了NoIcon没有之外, 其余4个都有, 其效果与代码都是效果的, 就是改变图标而已.

外加一个 about, 显示没有图标, 代码没有按钮.

# 创建消息盒子 (父窗口 / 标题 / 内容 / 按钮s / 默认(选中)按钮)ret = QMessageBox.question(self, 'Question', "The document has been modified.\nDo you want to save your changes?", QMessageBox.Yes | QMessageBox.No, QMessageBox.No)# 除了上述4种外(除NoIcon), 还有个 aboutret = QMessageBox.about(self, 'About', "The document has been modified.")

效果:

按钮:

中文按钮名:

默认的按钮名都是英文的, 若要中文显示则需要处理.

# 如果要中文按钮名, 则要自己添加按钮msgBox = QMessageBox(self)disconnectbtn = msgBox.addButton("中文按钮", QMessageBox.ActionRole)abortbtn = msgBox.addButton(QMessageBox.Abort)msgBox.exec_()if msgBox.clickedButton() == disconnectbtn:passelif msgBox.clickedButton() == abortbtn:pass

效果:

案例:

举个栗子, 我们在关闭窗口时弹出消息盒子.

def closeEvent(self, event):'''举个栗子, 我们在关闭窗口时弹出消息盒子.'''msgBox = QMessageBox(self)msgBox.setWindowTitle('关闭')msgBox.setText('是否保存?')msgBox.setIcon(QMessageBox.Question)btn_dontsave = msgBox.addButton('不保存', QMessageBox.AcceptRole)btn_cancel = msgBox.addButton('取消', QMessageBox.RejectRole)btn_save = msgBox.addButton('保存', QMessageBox.AcceptRole)msgBox.setDefaultButton(btn_save)msgBox.exec_()if msgBox.clickedButton() == btn_dontsave:print('不保存')event.accept()elif msgBox.clickedButton() == btn_cancel:event.ignore()elif msgBox.clickedButton() == btn_save:print('保存')event.accept()

效果:

QInputDialog 可输入对话框

输入对话框由 一个文本框 和 两个按钮组成, 用户点击ok(或 Enter 键), Dialog收集输入数据返回.

text, ok = QInputDialog.getText(self, 'getText', '请输入文本')if ok and text:print(text)text, ok = QInputDialog.getMultiLineText(self, 'getMultiLineText', '请输入文本', "默认文本")if ok and text:print(text)# 父控件 / 标题 / 文本 / 默认值 / 最小值 / 最大值 / 小数位数double, ok = QInputDialog.getDouble(self, 'getDouble', '请输入浮点数', 37.56, -10000, 10000, 2)if ok:print(double)# 父控件 / 标题 / 文本 / 默认值 / 最小值 / 最大值 / 步进int, ok = QInputDialog.getInt(self, 'getInteger', '请输入整数', 25, 0, 100, 1)if ok:print(int)items = ["Spring", "Summer", "Fall", "Winter"]# 父控件 / 标题 / 文本 / list of strings 数据 / 默认值 / 可编辑item, ok = QInputDialog.getItem(self, 'getItem', '请选择条目', items, 0, False)if ok and item:print(item)

效果:

中文按钮名:

dialog = QInputDialog(self)dialog.setWindowTitle('getText')dialog.setLabelText('请输入文本')dialog.setOkButtonText('确定')dialog.setCancelButtonText('取消')ok = dialog.exec_()text = dialog.textValue()if ok and text:print(text)

效果

QFontDialog 字体选择对话框

用户可以选择文本的字号大小 / 样式 / 格式 等.

def initUI(self):btn = QPushButton('打开字体选择对话框', self)btn.clicked.connect(self.showDialog)self.lbl = QLabel('Knowledge only matters', self)self.lbl.move(0, 50)self.setGeometry(300, 300, 550, 350)self.setWindowTitle('Dialog')self.show()def showDialog(self):font, ok = QFontDialog.getFont()if ok:self.lbl.setFont(font)self.lbl.adjustSize()

效果:

中文按钮及汉化:

使用系统翻译库吧

QFileDialog 文件对话框

用于文件的打开和保存, 可以打开指定扩展名的文件, 也可以设置起始目录.

# (标题 / 默认路径['/home' | 'C:\我的电脑'] / 过滤文件类型)# 路径: "."代表程序运行路径(默认) / "/"代表根目录(win+linux)fname = QFileDialog.getOpenFileName(self, 'Open file', 'C:\我的电脑', 'Image files (*.jpg *.png *.gif)')# ('C:/5560WIA.txt', 'All Files (*)')# ('C:/我的电脑/xxx.png', 'Image files (*.jpg *.png *.gif)')print(fname)files = QFileDialog.getOpenFileNames(self, "Select one or more files to open", ".", "Images (*.png *.xpm *.jpg)")dir = QFileDialog.getExistingDirectory(self, "Open Directory", ".", QFileDialog.ShowDirsOnly | QFileDialog.DontResolveSymlinks)fileName = QFileDialog.getSaveFileName(self, "Save File", "C:\我的电脑\\untitled.png", "Images (*.png *.xpm *.jpg)")

当然也可以分别设置:

dialog = QFileDialog()dialog.setFileMode(QFileDialog.AnyFile)if dialog.exec_():filename = dialog.selectedFiles()print(filename) # ['C:/Code/Python/PyQt5Demo2/icon.png']

效果:

窗口显示模式, 不过在win10上没效果

dialog.setViewMode(QFileDialog.Detail) # 设置视图模式 (win10没效果)

必选文件模式:

dialog.setFileMode(QFileDialog.AnyFile) # 指定必选文件模式

过滤写法:

'''过滤单个:Images (*.png *.xpm *.jpg)过滤多个:"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"'''dialog.setNameFilter("Images (*.png *.xpm *.jpg)") # 设置过滤文件名类型

中文按钮及汉化

不存在该问题, 调用的是系统控件

QColorDialog 颜色选择对话框

self.frm = QFrame(self)self.frm.setGeometry(10, 10, 100, 100)# 默认颜色 / 父控件 / 标题col = QColorDialog.getColor(Qt.blue, self, '选择颜色')if col.isValid():self.frm.setStyleSheet("QWidget { background-color: %s }" % col.name())

效果:

直接创建颜色:

col = QColor(0, 0, 0)

中文按钮及汉化:

使用系统翻译库吧

QProgressDialog 进度对话框

def initUI(self):self.min = 0self.max = 100self.progress = QProgressDialog("Copying files...", "Abort Copy", self.min, self.max, self)self.progress.setWindowModality(Qt.WindowModal)self.progress.canceled.connect(self.cancel)self.timer = QBasicTimer()self.step = 0if self.timer.isActive():self.timer.stop()else:self.timer.start(100, self)self.setGeometry(300, 300, 550, 350)self.setWindowTitle('Dialog')self.show()def timerEvent(self, e):if self.step >= self.max:self.timer.stop()return# ... copy one fileself.step = self.step + 1self.progress.setValue(self.step)def cancel(self):print("你Y的, 竟然取消了")self.timer.stop()

效果:

中文按钮及汉化:

全换成中文就好了

QErrorMessage 错误提示

# 方式一err = QErrorMessage(self)err.showMessage("这是显示的错误信息")# 方式二 默认输出错误信息, 没有则创建, 推荐该方法QErrorMessage.qtHandler().showMessage("这里显示的错误信息")

show this message again√去掉, 下次显示将不执行(不显示)

效果:

中文按钮及汉化:

使用系统翻译库吧

QWizard 向导窗

一般用在安装应用时, 或者第一次启动应用时.

向导窗由多个向导页(QWizardPage)组成, 通过以下addPage()方法添加向导页到向导窗(QWizard)

class MyWizard(QWizard):def __init__(self):super().__init__()self.initUI()def initUI(self):self.addPage(WizardPage())self.setWizardStyle(QWizard.ClassicStyle)self.setWindowTitle("Trivial Wizard")# self.show()

QWizardPage向导页:

class WizardPage(QWizardPage):def __init__(self):super().__init__()self.initUI()def initUI(self):'''向导页'''self.setTitle("Introduction")label = QLabel("This wizard will help you register your copy of Super Product Two.")label.setWordWrap(True)layout = QVBoxLayout()layout.addWidget(label)self.setLayout(layout)

内容显示位置:

样式:

self.wizard.setWizardStyle(QWizard.ClassicStyle)

虽然官方给的样式图是这样的, 但是实际显示效果则未必.

按条件调整展示向导页顺序

默认情况下是按id递增显示的, 我们可以重写QWizardPage.nextId()提供动态的顺序.

设置id (使用.setPage()来代替.addPage()):

self.setPage(1, IntroPage())self.setPage(2, EvaluatePage())self.setStartId(1) # 开始页

重写QWizardPage.nextId():

def nextId(self):'''返回下一页的id'''if self.upgradeKeyLineEdit.text().isEmpty():return 1 # 没有下一页返回 -1else:return 2

按钮

按钮布局:

设置按钮水平的位置, 会与其他位置配置(如: .setOption())发生冲突, 而使其他位置配置失效.

layout = [QWizard.Stretch, QWizard.BackButton, QWizard.CancelButton, QWizard.NextButton, QWizard.FinishButton]self.setButtonLayout(layout)

使用与不是QWizard.Stretch的区别:

选择权:

self.setOption(QWizard.NoBackButtonOnStartPage, True)

自定义按钮:

def initUI(self):...self.setButtonText(QWizard.CustomButton1, "猜猜我是谁")self.setOption(QWizard.HaveCustomButton1, True)self.customButtonClicked.connect(self.printButtonClicked)def printButtonClicked(self, which):text = self.button(which).text()print(text)

中文按钮及汉化:

self.setButtonText(QWizard.FinishButton, '大功告成')

直接使用系统翻译即可

图片

设置图片:

使用时需结合样式才有效果

self.setPixmap(QWizard.WatermarkPixmap, QPixmap('background.png'))

设置控件:

将控件设置在向导的左侧, 有使用WatermarkPixmap (ClassicStyle / ModernStyle)时设置在水印上方, 其他样式或没有使用水印时, 设置在向导左侧.

btn = QPushButton()btn.setText("按钮")layout = QVBoxLayout()layout.addWidget(btn)widget = QWidget()widget.setLayout(layout)self.setSideWidget(widget)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。