如何用PyQt5信号实现MVC模式来处理长尾词查询?

2026-04-20 10:382阅读0评论SEO资源
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计2256个文字,预计阅读时间需要10分钟。

如何用PyQt5信号实现MVC模式来处理长尾词查询?

MVC模式是Python开发中常用的一种架构模式。在PyQt5框架中实现MVC模式,中文资料相对较少。目前,我只找到了一篇较为优质的中文文档。以下是一些学习PyQt5实现MVC模式的建议:

1. 搭建学习环境:确保你的计算机上已安装PyQt5和相关依赖库。

2. 阅读优质文档:找到一篇关于PyQt5实现MVC模式的中文文档,仔细阅读,理解其核心概念和实现方法。

3. 动手实践:根据文档中的示例,尝试自己编写代码,将MVC模式应用到PyQt5项目中。

4. 加入社区:加入PyQt5相关的社区或论坛,与其他开发者交流学习经验,获取更多资源。

5. 参考英文资料:由于中文资料较少,可以参考英文资料,如官方文档、博客文章等,加深对MVC模式和PyQt5的理解。

6. 持续学习:PyQt5和MVC模式都是不断发展的技术,持续关注新动态,不断学习新的知识和技巧。

以下是一个简单的PyQt5实现MVC模式的示例:

pythonimport sysfrom PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget

模型class Model: def __init__(self): self.count=0

def increment(self): self.count +=1

视图class View(QWidget): def __init__(self, model): super().__init__() self.model=model self.initUI()

def initUI(self): self.layout=QVBoxLayout() self.button=QPushButton(Increment, self) self.button.clicked.connect(self.on_button_clicked) self.count_label=QLabel(Count: 0, self) self.layout.addWidget(self.button) self.layout.addWidget(self.count_label) self.setLayout(self.layout)

def on_button_clicked(self): self.model.increment() self.count_label.setText(fCount: {self.model.count})

控制器class Controller: def __init__(self, model, view): self.model=model self.view=view

def on_button_clicked(self): self.model.increment() self.view.on_button_clicked()

主程序if __name__==__main__: app=QApplication(sys.argv) model=Model() view=View(model) controller=Controller(model, view) view.show() sys.exit(app.exec_())

希望这能帮助你入门PyQt5和MVC模式!

众所周知MVC是个好东西。前阵子网上搜了下,但关于用PyQt5实现MVC的中文文档缺少之又少,优质的文档只搜到了一篇。既然这样,来,开个坑,学习新知识,吸引流量。话说,关于PyQt5,布局那里需要好好看看,容器类控件需要好好看看,还有多线程和自动化测试那块。但要写出完美GUI需要大量的代码经验和文档查询的能力。然后,嗯,这部分坑就填完了。

扯回正题:假设此时面临的场景是,一个软件涉及好几个页面,每个页面是单独的代码。且每个页面需要有自己的controller,最终所有的controller汇总到一起,统一管理。

本文中,文字只是辅助理解,务必读懂代码。

信号

众所周知,GUI中当一个控件的状态改变时需要通知另一个控件,也就是实现了对象间的通信。当事件发生或状态改变时,就会发出信号,信号会触发与这个事件相关联的函数,我们这个函数为槽。信号与槽可以是多对多的关系。信号在类创建时定义,即需要在初始化的前面定义。

自定义信号与槽

别问,静静感受以下代码。以下的代码中,已经包含了信号的定义、指定参数的类型、发射、绑定槽函数等一系列过程。

from PyQt5.QtCore import QObject, pyqtSignal # 信号对象 class QSignal(QObject): # 定义信号 # 在类创建时定义,不能在类创建后作为类的属性而添加 # 指定信号传递参数的数量,类型等 send_msg = pyqtSignal(str, str) def __init__(self): super(QSignal, self).__init__() def run(self): # 信号发射 self.send_msg.emit('First arg', 'Second arg') # 槽对象 class QSlot(QObject): def __init__(self): super(QSlot, self).__init__() def get(self, *args): # 信号接收 print("Get message =>" + args[0], args[1], sep=', ') if __name__ == '__main__': send = QSignal() slot = QSlot() # 将信号与槽函数绑定 send.send_msg.connect(slot.get) # 外部调用 发射信号 send.run() # 信号与槽解除关联 send.send_msg.disconnect(slot.get) send.run()

内置信号绑定自定义槽

这样,再来看一个和窗口结合的实例。窗口中有一个按钮,点击按钮就退出窗口。虽然这个例子很简单,不用信号和槽也能实现。但这里给个例子静心感受下:信号连接、发射、接收的全逻辑。

import sys from functools import partial from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QWidget, QHBoxLayout) class MainWindow(QMainWindow): btn_signal = pyqtSignal() def __init__(self): super(MainWindow, self).__init__() a = QPushButton("退出") # 给绑定的槽函数增加额外信息 a.clicked.connect(partial(self.btn_clicked, 1)) self.btn_signal.connect(self.close) self.setWindowTitle("演示") main_widget = QWidget() layout = QHBoxLayout() layout.addWidget(a) main_widget.setLayout(layout) # QMainWindow 不能设置布局 self.setCentralWidget(main_widget) def btn_clicked(self, n): print(n) self.btn_signal.emit() def close(self): app = QApplication.instance() app.quit() if __name__ == "__main__": # 在shell中执行 app = QApplication(sys.argv) mywin = MainWindow() mywin.show() # 开始主循环,直到退出 sys.exit(app.exec())

这里,想给绑定的槽函数btn_clicked传递额外参数,但信号绑定时不能添加额外参数。对应到上述例子中,close()可以通过指定信号的参数和类型来增加参数,但btn_clicked()不能。一种解决方案是掏出万能的partial函数,将函数和参数绑定在一起。

至此,应该了解了信号的工作方式和原理。而关于信号更多的内容,如重载、装饰器等,这里不做更多介绍,详情参考官方文档。话说,也佩服当年的学习方式:『把所有代码敲一遍』。时至今日也忘记了大多控件的含义和各种样式的代码,变成了:到时候去查API。

如何用PyQt5信号实现MVC模式来处理长尾词查询?

MVC

MVC的大名应该都听说过,model, view 和 control,即数据库、页面和处理逻辑相分离,这样写出来的代码更加专一化。这里给份代码感受下,三个内容用三个类所实现,个人不建议这样写,建议将文件放到三个文件夹下,而不是扔进一份代码里:

import sys from PyQt5 import QtCore from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QPushButton, QMessageBox, QLineEdit, QApplication) # View class MainWindow(QWidget): verifySignal = QtCore.pyqtSignal() def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.id_line = QLineEdit() self.id_line.setPlaceholderText("请输入账号") self.psd_line = QLineEdit() self.psd_line.setPlaceholderText("请输入密码") self.init() def init(self): layout = QHBoxLayout() self.setLayout(layout) self.button = QPushButton("登录") layout.addWidget(self.button) layout.addWidget(self.id_line) layout.addWidget(self.psd_line) # 连接定义的信号 self.button.clicked.connect(self.verify_emit) def verify_emit(self): self.verifySignal.emit() def verify_ok(self): QMessageBox.about(self, "密码正确", "已经登录") def verify_no(self): QMessageBox.about(self, "你犯了一个粗误", "请重新检查输入") # model class Student(object): def __init__(self): self.name = "aaa" self.password = "aaa" # control class LoginControll(object): def __init__(self): # 不需要从命令行输入参数 self._app = QApplication([]) self._model = Student() self._view = MainWindow() self.init() def init(self): self._view.verifySignal.connect(self.verify_user) def verify_user(self): id_ = self._view.id_line.text() psd_ = self._view.psd_line.text() if id_ == self._model.name and psd_ == self._model.password: self._view.verify_ok() else: self._view.verify_no() def run(self): self._view.show() # 事件循环,直到应用退出 return self._app.exec_() # main.py if __name__ == "__main__": login_control_ = LoginControll() # 退出主程序 sys.exit(login_control_.run())

在这个例子里需要注意的是,将model,view和controller分成了三个类。在view中定义信号以及信号何时发射,在controller中定义信号发射后连接的槽函数,即触发何种的响应。这样,通过信号的发射与连接,就将view和controller绑定在了一起。view负责页面展示与信号定义,controller负责信号的连接与功能的实现,完美。

MVC实现

单页面

如果读懂以上内容,那么应该可以实战了。首先给出一个demo,就是将上面最简单的MVC的例子拆分为三个文件。这里不便代码展示,请移步到我的github进行观看,这是文件结构,这是主文件。

多页面

在实现个复杂点的逻辑,多个页面,多个controller,文件结构如下所示,一个主文件,配三个文件夹,完美。这里命名时尽量规范,文件名、类名、函数名,不然容易把自己搞晕了。python main.py执行。

MVC-demo ├─ main.py ├─ UI │ ├─ leftbtn_ui.py │ ├─ login_ui.py │ ├─ main_window_ui.py │ └─ verify_ui.py ├─ control │ ├─ controller.py │ ├─ leftbtn_control.py │ ├─ login_control.py │ └─ verify_control.py └─ model └─ model.py

调用关系如下:

这里需要注意的是变量的生存周期,main调用controller,controller调用其它的子controller,很容易在声明一个类后局部变量消失,导致信号无法连接。如在controller.py中,典型错误的写法:

class Controll(object): def __init__(self): self._app = QApplication([]) self._stu = Student() self._view = MainWindow() self.init() def init(self): # 子 controller 作为局部变量,调用完后立刻消失,所以无法连接信号和槽 # 这个问题困扰了我三天,可真是滑稽 login_controller = login_control.Controller(self._view, self._stu.name, self._stu.password)

因为代码文件实在太多且混乱,就不在这里展示了,不然读者会更容易感到乱。这里只展示一个效果,完整代码见我的github。其实看一个例子,就啥都懂了。

以上就是PyQt5通过信号实现MVC的示例的详细内容,更多关于PyQt5通过信号实现MVC的资料请关注易盾网络其它相关文章!

本文共计2256个文字,预计阅读时间需要10分钟。

如何用PyQt5信号实现MVC模式来处理长尾词查询?

MVC模式是Python开发中常用的一种架构模式。在PyQt5框架中实现MVC模式,中文资料相对较少。目前,我只找到了一篇较为优质的中文文档。以下是一些学习PyQt5实现MVC模式的建议:

1. 搭建学习环境:确保你的计算机上已安装PyQt5和相关依赖库。

2. 阅读优质文档:找到一篇关于PyQt5实现MVC模式的中文文档,仔细阅读,理解其核心概念和实现方法。

3. 动手实践:根据文档中的示例,尝试自己编写代码,将MVC模式应用到PyQt5项目中。

4. 加入社区:加入PyQt5相关的社区或论坛,与其他开发者交流学习经验,获取更多资源。

5. 参考英文资料:由于中文资料较少,可以参考英文资料,如官方文档、博客文章等,加深对MVC模式和PyQt5的理解。

6. 持续学习:PyQt5和MVC模式都是不断发展的技术,持续关注新动态,不断学习新的知识和技巧。

以下是一个简单的PyQt5实现MVC模式的示例:

pythonimport sysfrom PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget

模型class Model: def __init__(self): self.count=0

def increment(self): self.count +=1

视图class View(QWidget): def __init__(self, model): super().__init__() self.model=model self.initUI()

def initUI(self): self.layout=QVBoxLayout() self.button=QPushButton(Increment, self) self.button.clicked.connect(self.on_button_clicked) self.count_label=QLabel(Count: 0, self) self.layout.addWidget(self.button) self.layout.addWidget(self.count_label) self.setLayout(self.layout)

def on_button_clicked(self): self.model.increment() self.count_label.setText(fCount: {self.model.count})

控制器class Controller: def __init__(self, model, view): self.model=model self.view=view

def on_button_clicked(self): self.model.increment() self.view.on_button_clicked()

主程序if __name__==__main__: app=QApplication(sys.argv) model=Model() view=View(model) controller=Controller(model, view) view.show() sys.exit(app.exec_())

希望这能帮助你入门PyQt5和MVC模式!

众所周知MVC是个好东西。前阵子网上搜了下,但关于用PyQt5实现MVC的中文文档缺少之又少,优质的文档只搜到了一篇。既然这样,来,开个坑,学习新知识,吸引流量。话说,关于PyQt5,布局那里需要好好看看,容器类控件需要好好看看,还有多线程和自动化测试那块。但要写出完美GUI需要大量的代码经验和文档查询的能力。然后,嗯,这部分坑就填完了。

扯回正题:假设此时面临的场景是,一个软件涉及好几个页面,每个页面是单独的代码。且每个页面需要有自己的controller,最终所有的controller汇总到一起,统一管理。

本文中,文字只是辅助理解,务必读懂代码。

信号

众所周知,GUI中当一个控件的状态改变时需要通知另一个控件,也就是实现了对象间的通信。当事件发生或状态改变时,就会发出信号,信号会触发与这个事件相关联的函数,我们这个函数为槽。信号与槽可以是多对多的关系。信号在类创建时定义,即需要在初始化的前面定义。

自定义信号与槽

别问,静静感受以下代码。以下的代码中,已经包含了信号的定义、指定参数的类型、发射、绑定槽函数等一系列过程。

from PyQt5.QtCore import QObject, pyqtSignal # 信号对象 class QSignal(QObject): # 定义信号 # 在类创建时定义,不能在类创建后作为类的属性而添加 # 指定信号传递参数的数量,类型等 send_msg = pyqtSignal(str, str) def __init__(self): super(QSignal, self).__init__() def run(self): # 信号发射 self.send_msg.emit('First arg', 'Second arg') # 槽对象 class QSlot(QObject): def __init__(self): super(QSlot, self).__init__() def get(self, *args): # 信号接收 print("Get message =>" + args[0], args[1], sep=', ') if __name__ == '__main__': send = QSignal() slot = QSlot() # 将信号与槽函数绑定 send.send_msg.connect(slot.get) # 外部调用 发射信号 send.run() # 信号与槽解除关联 send.send_msg.disconnect(slot.get) send.run()

内置信号绑定自定义槽

这样,再来看一个和窗口结合的实例。窗口中有一个按钮,点击按钮就退出窗口。虽然这个例子很简单,不用信号和槽也能实现。但这里给个例子静心感受下:信号连接、发射、接收的全逻辑。

import sys from functools import partial from PyQt5.QtCore import pyqtSignal from PyQt5.QtWidgets import (QMainWindow, QApplication, QPushButton, QWidget, QHBoxLayout) class MainWindow(QMainWindow): btn_signal = pyqtSignal() def __init__(self): super(MainWindow, self).__init__() a = QPushButton("退出") # 给绑定的槽函数增加额外信息 a.clicked.connect(partial(self.btn_clicked, 1)) self.btn_signal.connect(self.close) self.setWindowTitle("演示") main_widget = QWidget() layout = QHBoxLayout() layout.addWidget(a) main_widget.setLayout(layout) # QMainWindow 不能设置布局 self.setCentralWidget(main_widget) def btn_clicked(self, n): print(n) self.btn_signal.emit() def close(self): app = QApplication.instance() app.quit() if __name__ == "__main__": # 在shell中执行 app = QApplication(sys.argv) mywin = MainWindow() mywin.show() # 开始主循环,直到退出 sys.exit(app.exec())

这里,想给绑定的槽函数btn_clicked传递额外参数,但信号绑定时不能添加额外参数。对应到上述例子中,close()可以通过指定信号的参数和类型来增加参数,但btn_clicked()不能。一种解决方案是掏出万能的partial函数,将函数和参数绑定在一起。

至此,应该了解了信号的工作方式和原理。而关于信号更多的内容,如重载、装饰器等,这里不做更多介绍,详情参考官方文档。话说,也佩服当年的学习方式:『把所有代码敲一遍』。时至今日也忘记了大多控件的含义和各种样式的代码,变成了:到时候去查API。

如何用PyQt5信号实现MVC模式来处理长尾词查询?

MVC

MVC的大名应该都听说过,model, view 和 control,即数据库、页面和处理逻辑相分离,这样写出来的代码更加专一化。这里给份代码感受下,三个内容用三个类所实现,个人不建议这样写,建议将文件放到三个文件夹下,而不是扔进一份代码里:

import sys from PyQt5 import QtCore from PyQt5.QtWidgets import (QWidget, QHBoxLayout, QPushButton, QMessageBox, QLineEdit, QApplication) # View class MainWindow(QWidget): verifySignal = QtCore.pyqtSignal() def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.id_line = QLineEdit() self.id_line.setPlaceholderText("请输入账号") self.psd_line = QLineEdit() self.psd_line.setPlaceholderText("请输入密码") self.init() def init(self): layout = QHBoxLayout() self.setLayout(layout) self.button = QPushButton("登录") layout.addWidget(self.button) layout.addWidget(self.id_line) layout.addWidget(self.psd_line) # 连接定义的信号 self.button.clicked.connect(self.verify_emit) def verify_emit(self): self.verifySignal.emit() def verify_ok(self): QMessageBox.about(self, "密码正确", "已经登录") def verify_no(self): QMessageBox.about(self, "你犯了一个粗误", "请重新检查输入") # model class Student(object): def __init__(self): self.name = "aaa" self.password = "aaa" # control class LoginControll(object): def __init__(self): # 不需要从命令行输入参数 self._app = QApplication([]) self._model = Student() self._view = MainWindow() self.init() def init(self): self._view.verifySignal.connect(self.verify_user) def verify_user(self): id_ = self._view.id_line.text() psd_ = self._view.psd_line.text() if id_ == self._model.name and psd_ == self._model.password: self._view.verify_ok() else: self._view.verify_no() def run(self): self._view.show() # 事件循环,直到应用退出 return self._app.exec_() # main.py if __name__ == "__main__": login_control_ = LoginControll() # 退出主程序 sys.exit(login_control_.run())

在这个例子里需要注意的是,将model,view和controller分成了三个类。在view中定义信号以及信号何时发射,在controller中定义信号发射后连接的槽函数,即触发何种的响应。这样,通过信号的发射与连接,就将view和controller绑定在了一起。view负责页面展示与信号定义,controller负责信号的连接与功能的实现,完美。

MVC实现

单页面

如果读懂以上内容,那么应该可以实战了。首先给出一个demo,就是将上面最简单的MVC的例子拆分为三个文件。这里不便代码展示,请移步到我的github进行观看,这是文件结构,这是主文件。

多页面

在实现个复杂点的逻辑,多个页面,多个controller,文件结构如下所示,一个主文件,配三个文件夹,完美。这里命名时尽量规范,文件名、类名、函数名,不然容易把自己搞晕了。python main.py执行。

MVC-demo ├─ main.py ├─ UI │ ├─ leftbtn_ui.py │ ├─ login_ui.py │ ├─ main_window_ui.py │ └─ verify_ui.py ├─ control │ ├─ controller.py │ ├─ leftbtn_control.py │ ├─ login_control.py │ └─ verify_control.py └─ model └─ model.py

调用关系如下:

这里需要注意的是变量的生存周期,main调用controller,controller调用其它的子controller,很容易在声明一个类后局部变量消失,导致信号无法连接。如在controller.py中,典型错误的写法:

class Controll(object): def __init__(self): self._app = QApplication([]) self._stu = Student() self._view = MainWindow() self.init() def init(self): # 子 controller 作为局部变量,调用完后立刻消失,所以无法连接信号和槽 # 这个问题困扰了我三天,可真是滑稽 login_controller = login_control.Controller(self._view, self._stu.name, self._stu.password)

因为代码文件实在太多且混乱,就不在这里展示了,不然读者会更容易感到乱。这里只展示一个效果,完整代码见我的github。其实看一个例子,就啥都懂了。

以上就是PyQt5通过信号实现MVC的示例的详细内容,更多关于PyQt5通过信号实现MVC的资料请关注易盾网络其它相关文章!