【嵌入式学习5】PyQt布局- 信号和槽 - 按钮 - 对话框 - 面向对象
目录
1、布局
①水平布局 - QHBoxLayout
②垂直布局 - QVBoxLayout
③表单布局 - QFormLayout
④布局嵌套
2、信号和槽
①信号(Signal)
emit 方法:
②信号和槽(Slot)绑定
③使用PyQt槽函数
3、按钮
①QPushButton-普通按钮
②QRadioButton-单选框
③QCheckBox-复选框
4、对话框 - QDialog
①QMessageBox
②QInputDialog
5、区分addWidget、addLayout、setParent、setLayout
①addWidget和addLayout
②setparent和setlayout
6、面向对象
1、布局
多个控件在窗口中的展示方式,布局方式分为水平、垂直、网格、表单
①水平布局 - QHBoxLayout
from PyQt5.QtWidgets import *
import sys
class QHWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('水平布局示例')
# 创建布局
layout = QHBoxLayout()
btn1 = QPushButton('A')
btn2 = QPushButton('B')
btn3 = QPushButton('C')
btn4 = QPushButton('D')
btn5 = QPushButton('E')
# 添加布局到窗口中
self.setLayout(layout)
# 按钮控件添加到布局中
layout.addWidget(btn1)
layout.addWidget(btn2)
layout.addWidget(btn3)
layout.addWidget(btn4)
layout.addWidget(btn5)
if __name__ == '__main__':
app = QApplication(sys.argv)
qh = QHWindow()
qh.show()
sys.exit(app.exec())
②垂直布局 - QVBoxLayout
from PyQt5.QtWidgets import *
import sys
class QVWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('垂直布局示例')
# 创建布局
layout = QVBoxLayout()
btn1 = QPushButton('A')
btn2 = QPushButton('B')
btn3 = QPushButton('C')
btn4 = QPushButton('D')
btn5 = QPushButton('E')
# 添加布局到窗口中
self.setLayout(layout)
# 按钮控件添加到布局中
layout.addWidget(btn1)
layout.addWidget(btn2)
layout.addWidget(btn3)
layout.addWidget(btn4)
layout.addWidget(btn5)
if __name__ == '__main__':
app = QApplication(sys.argv)
qh = QVWindow()
qh.show()
sys.exit(app.exec())
③表单布局 - QFormLayout
from PyQt5.QtWidgets import *
import sys
def func(nameEdit,ageEdit,phoneEdit):
name = nameEdit.text()
age = ageEdit.text()
phone = phoneEdit.text()
print("姓名:{} 年龄:{} 电话:{}".format(name, age, phone))
class QFWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('表单布局示例')
layout = QFormLayout()
self.setLayout(layout)
nameEdit = QLineEdit()
ageEdit = QLineEdit()
phoneEdit = QLineEdit()
btn = QPushButton('提交')
# 使用 lambda 函数将参数传递给 func,确保 func 在按钮点击时被调用,而不是在连接信号时被调用
btn.clicked.connect(lambda:func(nameEdit,ageEdit,phoneEdit))
layout.addRow('姓名',nameEdit)
layout.addRow('年龄',ageEdit)
layout.addRow('电话',phoneEdit)
layout.addRow('',btn)
if __name__ == '__main__':
app = QApplication(sys.argv)
qf = QFWindow()
qf.show()
sys.exit(app.exec())
④布局嵌套
第一部分水平布局,第二部分第三部分垂直布局
from PyQt5.QtWidgets import *
import sys
class QTWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('嵌套布局示例')
# 整体水平布局
wholeLayout = QHBoxLayout()
self.setLayout(wholeLayout)
layout1 = QHBoxLayout()
layout2 = QVBoxLayout()
layout3 = QVBoxLayout()
wholeLayout.addLayout(layout1)
wholeLayout.addLayout(layout2)
wholeLayout.addLayout(layout3)
# 添加控件
layout1.addWidget(QPushButton('A'))
layout1.addWidget(QPushButton('B'))
layout2.addWidget(QPushButton('C'))
layout2.addWidget(QPushButton('D'))
layout3.addWidget(QPushButton('E'))
layout3.addWidget(QPushButton('F'))
layout3.addWidget(QPushButton('G'))
if __name__ == '__main__':
app = QApplication(sys.argv)
qt = QTWindow()
qt.show()
sys.exit(app.exec())
2、信号和槽
信号(Signal)和槽(Slot)是实现对象之间通信的核心机制。它们是 Qt 的事件驱动编程模型的基础,允许对象在某些事件发生时通知其他对象,并触发相应的处理函数。当一个特定事件发生的时候,signal
会被emit
出来,slot
调用是用来响应相应的signal
的
①信号(Signal)
信号是 Qt 对象发出的“通知”,表示某个事件已经发生。例如,当用户点击按钮时,按钮对象会发出一个 clicked
信号
定义信号 | |
QPushButton | clicked(点击时发送) |
QLineEdit | textChanged(文本框内容改变) |
QCheckBox | stateChanged(复选框状态改变) |
emit
方法:
用于触发信号,通知与该信号连接的所有槽函数(slot functions)执行。
from PyQt5.QtCore import pyqtSignal, QObject
class MyObject(QObject):
mySignal = pyqtSignal(str) # 定义一个带字符串参数的信号
# 当某个事件发生时(例如用户点击按钮、数据发生变化等),对象可以通过 emit 方法发出一个信号,通知其他对象该事件已经发生
def doSomething(self):
self.mySignal.emit("Hello, Signal!") # 发出信号
②信号和槽(Slot)绑定
通过调用QObject对象的connect函数来将对象的信号和另一个队形槽函数关联,当发射这发射信号,接收者的槽函数将被调用
# 点击按钮,输出对应内容
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
def click():
print('方法1收到点击信号a')
class SWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('信号与槽函数绑定示例')
btn = QPushButton()
btn.setText('点击发送信号a')
btn.setParent(self)
# 方法1:槽函数使用函数
btn.clicked.connect(click)
# 方法2:槽函数使用lambda表达式
btn.clicked.connect(lambda:print('方法2收到点击信号a'))
if __name__ == '__main__':
app = QApplication(sys.argv)
sw = SWindow()
sw.show()
sys.exit(app.exec())
③使用PyQt槽函数
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
class QWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('使用系统的槽函数')
btn = QPushButton()
btn.setText('关闭窗口')
btn.setParent(self)
btn.clicked.connect(QApplication.quit) # 使用QApplication的quit方法
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QWindow()
w.show()
sys.exit(app.exec())
3、按钮
①QPushButton-普通按钮
from PyQt5.QtWidgets import QWidget,QApplication,QPushButton
import sys
def func():
print('感谢投币!一键三连~')
class BWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('普通按钮控件展示')
btn = QPushButton()
btn.setText('投币')
btn.clicked.connect(func)
btn.setParent(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
bt = BWindow()
bt.show()
sys.exit(app.exec())
②QRadioButton-单选框
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import sys
def func(checked):
print('状态变化',checked)
class RWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('单选框示例')
# 横向布局
layout = QHBoxLayout()
self.setLayout(layout)
r1 = QRadioButton('点赞')
r2 = QRadioButton('投币')
r3 = QRadioButton('收藏')
r1.setChecked(True)
layout.addWidget(r1)
layout.addWidget(r2)
layout.addWidget(r3)
r1.toggled.connect(func)
if __name__ == '__main__':
app = QApplication(sys.argv)
rw = RWindow()
rw.show()
sys.exit(app.exec_())
# 如果想给QRadioButton组设置监听事件,可按照如下代码添加
# 声明槽函数
def on_group_toggle(btn: QRadioButton):
print(btn, btn.isChecked())
# 添加两个单选钮到QButtonGroup,并添加选中事件
group = QButtonGroup(w)
group.addButton(btn1)
group.addButton(btn2)
group.buttonToggled.connect(on_group_toggle)
③QCheckBox-复选框
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
def func(state):
# 判断是否选中
if state == Qt.Checked:
print('选中')
else:
print('未选中')
class CWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('复选框示例')
layout = QHBoxLayout()
self.setLayout(layout)
label = QLabel()
label.setText('请做出你的选择:')
ck1 = QCheckBox('点赞')
ck2 = QCheckBox('投币')
ck3 = QCheckBox('收藏')
ck1.setChecked(True)
layout.addWidget(label)
layout.addWidget(ck1)
layout.addWidget(ck2)
layout.addWidget(ck3)
ck1.stateChanged.connect(func)
if __name__ == '__main__':
app = QApplication(sys.argv)
cw = CWindow()
cw.show()
sys.exit(app.exec())
4、对话框 - QDialog
①QMessageBox
from PyQt5.QtWidgets import *
import sys
def close(qm):
res = QMessageBox.question(None,'warning','are you sure?',QMessageBox.Ok | QMessageBox.Cancel,QMessageBox.Cancel)
if res == QMessageBox.Ok:
print('closing')
qm.close()
elif res == QMessageBox.Cancel:
print('cancel')
class QMWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('对话框示例')
btn = QPushButton()
btn.setText('关闭游戏')
btn.setParent(self)
# lambda 常用于将参数传递给槽函数。例如,当你需要在信号连接时传递额外参数时,可以使用 lambda
btn.clicked.connect(lambda: close(self))
if __name__ == '__main__':
app = QApplication(sys.argv)
qm = QMWindow()
qm.show()
sys.exit(app.exec())
②QInputDialog
from PyQt5.QtWidgets import *
import sys
class QMWindow(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('输入提示框示例')
layout = QHBoxLayout()
self.setLayout(layout)
self.resize(400,350)
btn = QPushButton('添加英雄')
self.edit = QLineEdit()
layout.addWidget(btn)
layout.addWidget(self.edit)
btn.clicked.connect(self.input)
def input(self):
str,res = QInputDialog.getText(w,'warning','请输入英雄名称')
if res:
self.edit.setText(str)
print('添加%s成功'%str)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = QMWindow()
w.show()
sys.exit(app.exec())
5、区分addWidget、addLayout、setParent、setLayout
①addWidget和addLayout
addWidget | 布局管理器(如 QHBoxLayout 、QVBoxLayout 、QGridLayout 等)的方法,用于将控件(如按钮、标签、输入框等)添加到布局中。 |
|
|
addLayout | 布局管理器的方法,用于将一个子布局添加到当前布局中。这允许嵌套布局,实现更复杂的界面设计。 |
|
|
②setparent和setlayout
setparent | 控件(QWidget 或其子类)的方法,用于设置控件的父级。这会影响控件的显示和事件处理。 |
|
|
setlayout | 控件(QWidget 或其子类)的方法,用于设置控件的布局管理器。布局管理器负责管理控件内部的子控件的布局。 |
|
|
6、面向对象
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sys
# 窗口继承QWidget
class MyWindow(QWidget):
def __init__(self, title):
super().__init__()
self.setWindowTitle(title)
self.init_ui()
# 初始化UI
def init_ui(self):
layout = QHBoxLayout()
# ---------------------------------
# 在这里初始化界面内容
# ---------------------------------
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MyWindow("窗口标题")
window.show()
sys.exit(app.exec())