PyQt5 signal and slot
PyQt5 的 signal 与 slot 有所改变,例如,先定义一个 ZeroSignal 类:
class ZeroSignal(QObject):
atzero = pyqtSignal(int)
使用时,一是绑定 slot 如下:
self.zerosig = ZeroSignal()
self.zerosig.atzero[int].connect(self.countZero)
然后是找个机会发动之:
def checkZero(self):
if self.value() == 0:
self.zerosig.atzero.emit(self.value())
大约如此,完整代码如下:
import os
import sys from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import * class ZeroSignal(QObject):
atzero = pyqtSignal(int) class ZeroSpinBox(QSpinBox):
def __init__(self, parent=None):
super(ZeroSpinBox, self).__init__(parent)
self.zeros = 0
self.valueChanged[int].connect(self.checkZero)
self.zerosig = ZeroSignal()
self.zerosig.atzero[int].connect(self.countZero) def countZero(self, v):
if v == 0:
self.zeros += 1
print(self.zeros) def checkZero(self):
if self.value() == 0:
self.zerosig.atzero.emit(self.value()) class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent) dial = QDial()
dial.setNotchesVisible(True)
spin = ZeroSpinBox()
layout = QHBoxLayout()
layout.addWidget(dial)
layout.addWidget(spin)
self.setLayout(layout)
dial.valueChanged.connect(spin.setValue)
spin.valueChanged.connect(dial.setValue)
spin.valueChanged.connect(self.emitZero)
self.setWindowTitle("Sinal and Solt") self.zerobox = spin
self.zerobox.zerosig.atzero[int].connect(self.annouce) def emitZero(self, v):
if v == 0:
self.zerobox.zerosig.atzero.emit(self.zerobox.zeros) def annouce(self, v):
print("zero count: %d" % v) # print two times because add ZeroSpinBox emit once def run():
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_() if __name__ == '__main__':
run()
关于对话框的代码如下,尤其 NumberLiveDialog 值得推荐:
import sys,math,random,string
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import * class NumberDialog(QDialog):
def __init__(self, format, parent=None):
super(NumberDialog, self).__init__(parent) thousandsLabel = QLabel("&Thousands separator:")
self.thousandsEdit = QLineEdit(format["thousandsseparator"])
thousandsLabel.setBuddy(self.thousandsEdit)
decimalMarkerLabel = QLabel("Decimal $marker:")
self.decimalMarkerEdit = QLineEdit(format["decimalmarker"])
decimalMarkerLabel.setBuddy(self.decimalMarkerEdit)
decimalPlacesLabel = QLabel("&Decimal places:")
self.decimalPlacesSpinBox = QSpinBox()
decimalPlacesLabel.setBuddy(self.decimalPlacesSpinBox)
self.decimalPlacesSpinBox.setRange(0, 6)
self.decimalPlacesSpinBox.setValue(format["decimalplaces"])
self.redNegativesCheckBox = QCheckBox("&Red negative numbers")
self.redNegativesCheckBox.setChecked(format["rednegatives"]) buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.format = format.copy() grid = QGridLayout()
grid.addWidget(thousandsLabel, 0, 0)
grid.addWidget(self.thousandsEdit, 0, 1)
grid.addWidget(decimalMarkerLabel, 1, 0)
grid.addWidget(self.decimalMarkerEdit, 1, 1)
grid.addWidget(decimalPlacesLabel, 2, 0)
grid.addWidget(self.decimalPlacesSpinBox, 2, 1)
grid.addWidget(self.redNegativesCheckBox, 3, 0, 1, 2)
grid.addWidget(buttonBox, 4, 0, 1, 2)
self.setLayout(grid) buttonBox.accepted.connect(self.accept)
buttonBox.rejected.connect(self.reject)
self.setWindowTitle("Number format") def accept(self):
class ThousandsError(Exception): pass
class DecimalError(Exception): pass
Punctuation = frozenset(" ,;:.") thousands = str(self.thousandsEdit.text())
decimal = str(self.decimalMarkerEdit.text())
try:
if len(decimal) == 0:
raise DecimalError("The decimal marker may not be empty.")
if len(thousands) > 1:
raise ThousandsError("The thousands separator may only be empty or one charactor.")
if len(decimal) > 1:
raise DecimalError("The decimal marker must be one character.")
if thousands == decimal:
raise ThousandsError("The thousands separator and decimal marker must be different.")
if thousands and thousands not in Punctuation:
raise ThousandsError("The thousands separator must be in Punctuation.")
if decimal and decimal not in Punctuation:
raise DecimalError("The decimal marker must be a punctuation symbol.")
except ThousandsError as e:
QMessageBox.warning(self, "Thousands separator error:", str(e))
self.thousandsEdit.selectAll()
self.thousandsEdit.setFocus()
return
except DecimalError as e:
QMessageBox.warning(self, "Decimal marker error:", str(e))
self.decimalMarkerEdit.selectAll()
self.decimalMarkerEdit.setFocus()
return self.format["thousandsseparator"] = thousands
self.format["decimalmarker"] = decimal
self.format["decimalplaces"] = self.decimalPlacesSpinBox.value()
self.format["rednegatives"] = self.redNegativesCheckBox.isChecked() QDialog.accept(self) def numberFormat(self):
return self.format class NumberModelessDialog(QDialog):
changed = pyqtSignal() def __init__(self, format, parent=None):
super(NumberModelessDialog, self).__init__(parent)
self.setAttribute(Qt.WA_DeleteOnClose)
punctuationRe = QRegularExpression(r"[ ,;:.]") thousandsLabel = QLabel("&Thousands separator:")
self.thousandsEdit = QLineEdit(format["thousandsseparator"])
thousandsLabel.setBuddy(self.thousandsEdit)
self.thousandsEdit.setMaxLength(1)
self.thousandsEdit.setValidator(QRegularExpressionValidator(punctuationRe, self)) decimalMarkerLabel = QLabel("Decimal $marker:")
self.decimalMarkerEdit = QLineEdit(format["decimalmarker"])
decimalMarkerLabel.setBuddy(self.decimalMarkerEdit)
self.decimalMarkerEdit.setMaxLength(1)
self.decimalMarkerEdit.setValidator(QRegularExpressionValidator(punctuationRe, self)) decimalPlacesLabel = QLabel("&Decimal places:")
self.decimalPlacesSpinBox = QSpinBox()
decimalPlacesLabel.setBuddy(self.decimalPlacesSpinBox)
self.decimalPlacesSpinBox.setRange(0, 6)
self.decimalPlacesSpinBox.setValue(format["decimalplaces"]) self.redNegativesCheckBox = QCheckBox("&Red negative numbers")
self.redNegativesCheckBox.setChecked(format["rednegatives"]) buttonBox = QDialogButtonBox(QDialogButtonBox.Apply | QDialogButtonBox.Close)
self.format = format grid = QGridLayout()
grid.addWidget(thousandsLabel, 0, 0)
grid.addWidget(self.thousandsEdit, 0, 1)
grid.addWidget(decimalMarkerLabel, 1, 0)
grid.addWidget(self.decimalMarkerEdit, 1, 1)
grid.addWidget(decimalPlacesLabel, 2, 0)
grid.addWidget(self.decimalPlacesSpinBox, 2, 1)
grid.addWidget(self.redNegativesCheckBox, 3, 0, 1, 2)
grid.addWidget(buttonBox, 4, 0, 1, 2)
self.setLayout(grid) buttonBox.button(QDialogButtonBox.Apply).clicked.connect(self.apply)
buttonBox.rejected.connect(self.reject)
self.setWindowTitle("Number format") def apply(self):
thousands = str(self.thousandsEdit.text())
decimal = str(self.decimalMarkerEdit.text())
if thousands == decimal:
QMessageBox.warning(self, "Thousands separator error")
self.thousandsEdit.selectAll()
self.thousandsEdit.setFocus()
return
if len(decimal) == 0:
QMessageBox.warning(self, "Decimal marker cannot is empty.")
self.decimalMarkerEdit.selectAll()
self.decimalMarkerEdit.setFocus()
return self.format["thousandsseparator"] = thousands
self.format["decimalmarker"] = decimal
self.format["decimalplaces"] = self.decimalPlacesSpinBox.value()
self.format["rednegatives"] = self.redNegativesCheckBox.isChecked() self.changed.emit() class NumberLiveDialog(QDialog):
changed = pyqtSignal() def __init__(self, format, callback, parent=None):
super(NumberLiveDialog, self).__init__(parent)
self.format = format
self.callback = callback self.setAttribute(Qt.WA_DeleteOnClose)
punctuationRe = QRegularExpression(r"[ ,;:.]") thousandsLabel = QLabel("&Thousands separator:")
self.thousandsEdit = QLineEdit(format["thousandsseparator"])
thousandsLabel.setBuddy(self.thousandsEdit)
self.thousandsEdit.setMaxLength(1)
self.thousandsEdit.setValidator(QRegularExpressionValidator(punctuationRe, self)) decimalMarkerLabel = QLabel("Decimal $marker:")
self.decimalMarkerEdit = QLineEdit(format["decimalmarker"])
decimalMarkerLabel.setBuddy(self.decimalMarkerEdit)
self.decimalMarkerEdit.setMaxLength(1)
self.decimalMarkerEdit.setValidator(QRegularExpressionValidator(punctuationRe, self)) decimalPlacesLabel = QLabel("&Decimal places:")
self.decimalPlacesSpinBox = QSpinBox()
decimalPlacesLabel.setBuddy(self.decimalPlacesSpinBox)
self.decimalPlacesSpinBox.setRange(0, 6)
self.decimalPlacesSpinBox.setValue(format["decimalplaces"]) self.redNegativesCheckBox = QCheckBox("&Red negative numbers")
self.redNegativesCheckBox.setChecked(format["rednegatives"]) grid = QGridLayout()
grid.addWidget(thousandsLabel, 0, 0)
grid.addWidget(self.thousandsEdit, 0, 1)
grid.addWidget(decimalMarkerLabel, 1, 0)
grid.addWidget(self.decimalMarkerEdit, 1, 1)
grid.addWidget(decimalPlacesLabel, 2, 0)
grid.addWidget(self.decimalPlacesSpinBox, 2, 1)
grid.addWidget(self.redNegativesCheckBox, 3, 0, 1, 2)
self.setLayout(grid) self.thousandsEdit.textEdited.connect(self.checkAndFix)
self.decimalMarkerEdit.textEdited.connect(self.checkAndFix)
self.decimalPlacesSpinBox.valueChanged.connect(self.apply)
self.redNegativesCheckBox.toggled.connect(self.apply) self.setWindowTitle("Number format") def checkAndFix(self):
thousands = self.thousandsEdit.text()
decimal = self.decimalMarkerEdit.text()
if thousands == decimal:
self.thousandsEdit.clear()
self.thousandsEdit.setFocus()
if len(decimal) == 0:
self.decimalMarkerEdit.setText(".")
self.decimalMarkerEdit.selectAll()
self.decimalMarkerEdit.setFocus()
self.apply() def apply(self):
thousands = self.thousandsEdit.text()
decimal = self.decimalMarkerEdit.text() self.format["thousandsseparator"] = thousands
self.format["decimalmarker"] = decimal
self.format["decimalplaces"] = self.decimalPlacesSpinBox.value()
self.format["rednegatives"] = self.redNegativesCheckBox.isChecked() self.callback() class Form(QDialog):
X_MAX = 26
Y_MAX = 60 def __init__(self, parent=None):
super(Form, self).__init__(parent) self.numberDlg = None
self.format = { "thousandsseparator":",", "decimalmarker":".",
"decimalplaces":2, "rednegatives": False }
self.numbers = {}
for x in range(self.X_MAX):
for y in range(self.Y_MAX):
self.numbers[(x,y)] = 10000 * random.random() - 5000 self.table = QTableWidget()
modalButton = QPushButton("Set numbe format...(&Modal)")
modelessButton = QPushButton("Set number format...(M&odeless)")
liveButton = QPushButton("Set number format...(&Live)") buttonLayout = QHBoxLayout()
buttonLayout.addStretch()
buttonLayout.addWidget(modalButton)
buttonLayout.addWidget(modelessButton)
buttonLayout.addWidget(liveButton)
layout = QVBoxLayout()
layout.addWidget(self.table)
layout.addLayout(buttonLayout)
self.setLayout(layout) modalButton.clicked.connect(self.setNumberFormatByModal)
modelessButton.clicked.connect(self.setNumberFormatByModeless)
liveButton.clicked.connect(self.setNumberFormatByLive) self.setWindowTitle("Set Number Format")
self.refreshTable() def refreshTable(self):
self.table.clear()
self.table.setRowCount(self.Y_MAX)
self.table.setColumnCount(self.X_MAX)
self.table.setHorizontalHeaderLabels(list(string.ascii_uppercase)) for x in range(self.X_MAX):
for y in range(self.Y_MAX):
fraction, whole = math.modf(self.numbers[(x,y)])
sign = "-" if whole < 0 else ""
whole = "{0}".format(int(math.floor(abs(whole))))
digits = []
for i, digit in enumerate(reversed(whole)):
if i and i % 3 == 0:
digits.insert(0, self.format["thousandsseparator"])
digits.insert(0, digit)
if self.format["decimalplaces"]:
fraction = "{0:.7f}".format(abs(fraction))
fraction = self.format["decimalmarker"] + fraction[2:self.format["decimalplaces"]+2]
else:
fraction = ""
text = "{0}{1}{2}".format(sign, "".join(digits), fraction)
item = QTableWidgetItem(text)
item.setTextAlignment(Qt.AlignRight | Qt.AlignVCenter)
if sign and self.format["rednegatives"]:
item.setBackground(Qt.red)
self.table.setItem(y, x, item) def setNumberFormatByModal(self):
dlg = NumberDialog(self.format, self)
if dlg.exec_():
self.format = dlg.numberFormat()
self.refreshTable() def setNumberFormatByModeless(self):
dlg = NumberModelessDialog(self.format, self)
dlg.show()
dlg.changed.connect(self.refreshTable) def setNumberFormatByLive(self):
if self.numberDlg is None:
self.numberDlg = NumberLiveDialog(self.format, self.refreshTable, self)
self.numberDlg.show()
self.numberDlg.raise_()
self.numberDlg.activateWindow() if __name__ == "__main__":
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
numberdlg.py
关于主窗口 (fileload function need add a bool parameter for recentfiles) 的代码:imagechanger
运行效果图如下:

《Python GUI Qt 快速开放指南》部分例子:PyQt5-Code
PyQt5 signal and slot的更多相关文章
- 深入了解Qt(三)之元signal和slot
深入了解Qt主要内容来源于Inside Qt系列,本文做了部分删改,以便于理解.在此向原作者表示感谢! 在Qt 信号和槽函数这篇文章中已经详细地介绍了信号和槽的使用及注意事项.在这里对其使用方面的知识 ...
- 【golang-GUI开发】qt之signal和slot(一)
想了很久,我决定还是先从signal和slot(信号槽)开始讲起. signal和slot大家一定不陌生,先看一段示例(选自文档): class Counter : public QObject { ...
- Qt Signal and Slot
Qt4中的信号槽 Qt4中的信号槽是通过SIGNAL,SLOT两个宏,将参数转换成字符串.Qt编译前,会从源码的头文件中提取由signal和slot声明的信号和槽的函数, 将其组成一张信号和槽对应的字 ...
- qt的signal和slot机制
signal和slot是QT中的一大特点 signal/slot是Qt对象以及其派生类对象之间的一种高效通信接口 用户可以将N多个信号和单个槽相连接, 或者将将N个槽和单个信号连接, 甚至是一个信号和 ...
- [C++_QT] Error: Not a signal or slot declaration
问题: 在Qt工程中添加了一个新的窗口之后 一直报错 如下 单单从错误描述上看 是缺少信号或者槽 但是我确定没有缺少啊 然后第二个错误显示了一个mox_xxxx文件 然后我就去那个目录下去找那个文件 ...
- 【golang-GUI开发】qt之signal和slot(二)
上一篇文章里我们详细介绍了signal的用法. 今天我们将介绍slot的使用.在qt中slot和signal十分相像,这次我们将实现一个能显示16进制数字的SpinBox,它继承自QSpinbox并重 ...
- QT 中 关键字讲解(emit,signal,slot)
Qt中的类库有接近一半是从基类QObject上继承下来,信号与反应槽(signals/slot)机制就是用来在QObject类或其子类间通讯的方法.作为一种通用的处理机制,信号与反应槽非常灵活,可以携 ...
- qt信号signal和槽slot机制
内容: 一.概述 二.信号 三.槽 四.信号与槽的关联 五.元对象工具 六.程序样例 七.应注意的问题 信号与槽作为QT的核心机制在QT编程中有着广泛的应用,本文介绍了信号与槽的一些基本概念.元对象工 ...
- signal & slot
The Qt signals/slots and property system are based on the ability to introspect the objects at runti ...
随机推荐
- jquery遍历之children()与find()的区别
hildren(selector) 方法是返回匹配元素集合中每个元素的所有子元素(仅儿子辈).参数可选,添加参数表示通过选择器进行过滤,对元素进行筛选. .find(selector)方法是返回匹配元 ...
- NJCTF 2017 web pictures'wall(详解)
题目: 图片墙上有图片 url:http://218.2.197.235:23719/ writeup: 首先各种尝试登陆,发现任意用户及密码都可以登陆,但登陆后的页面提示的是“Root has pr ...
- MapReduce Design Patterns(chapter 2(part 1))(二)
随着每天都有更多的数据加载进系统,数据量变得很庞大.这一章专注于对你的数据顶层的,概括性意见的设计模式,从而使你能扩展思路,但可能对局部数据是不适用的.概括性的分析都是关于对相似数据的分组和执行统计运 ...
- 二进制安装mariaDB
1.获取二进制安装包 获取二进制格式MariaDB安装包,可去官网下载. 因为是实验环境,所以选择了最新版. mariadb-10.2.12-linux-x86_64.tar.gz 2.解压 解压到 ...
- Windows平台下Android应用抓包挖掘漏洞方法
0x01 大体思路 在安卓75%的市场占有率下,形形色色的安卓应用层出不穷,随之而来的便是大波的漏洞.在各类市场中随意翻一下,几乎都是连接网络的应用,这在给用户惬意体验的同时也给我们漏洞挖掘带来了机会 ...
- keepalived.md
配置文件说明 global_defs区域 global_defs { notification_email { acassen@firewall.loc failover@firewall.loc s ...
- SOJ 1089 FatMouse的奶酪 暴力
BackGround FatMouse拥有许多奶酪,所有的奶酪都有一个彼此不同的重量.FatMouse为了控制它自己的体重,在每天早上它都会计算今天应该吃多少奶酪才能无痛苦地减肥. The Probl ...
- apache2 重启、停止、优雅重启、优雅停止
停止或者重新启动Apache有两种发送信号的方法 第一种方法: 直接使用linux的kill命令向运行中的进程发送信号.你也许你会注意到你的系统里运行着很多httpd进程.但你不应该直接对它们中的任何 ...
- 说说Vue.js的v-for
v-for的话,相比传统的jQuery的 $.each或者for循环要简洁明了的多, 比如在Jquery中我要遍历数据,通常如下几种方式: $.each(apps, function(i, app) ...
- Java性能监控
Java性能监控 上次介绍了如何使用jvisualvm监控java,今天做进一步讲解!Java性能监控主要关注CPU.内存和线程. 在线程页中,点击线程Dump,可以生成threaddump日志,通过 ...