好湿?好紧?好多水好爽自慰,久久久噜久噜久久综合,成人做爰A片免费看黄冈,机机对机机30分钟无遮挡

主頁 > 知識庫 > PyQt5通過信號實現MVC的示例

PyQt5通過信號實現MVC的示例

熱門標簽:柳州正規電銷機器人收費 鎮江人工外呼系統供應商 外呼系統前面有錄音播放嗎 深圳網絡外呼系統代理商 400電話辦理費用收費 高德地圖標注字母 千呼ai電話機器人免費 申請辦個400電話號碼 騰訊地圖標注有什么版本

眾所周知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。

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的資料請關注腳本之家其它相關文章!

您可能感興趣的文章:
  • PyQt5 matplotlib畫圖不刷新的解決方案
  • PyQt5 設置窗口全屏顯示方式
  • Pyqt5 實現窗口縮放,控件在窗口內自動伸縮的操作
  • 解決PyQt5 無邊框后窗口的移動問題
  • PyQt5 實現給無邊框widget窗口添加背景圖片
  • PyQt5中QSpinBox計數器的實現
  • pyqt5 設置窗體透明控件不透明的操作

標簽:烏蘭察布 平頂山 大慶 合肥 哈爾濱 烏蘭察布 郴州 海南

巨人網絡通訊聲明:本文標題《PyQt5通過信號實現MVC的示例》,本文關鍵詞  PyQt5,通過,信號,實現,MVC,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《PyQt5通過信號實現MVC的示例》相關的同類信息!
  • 本頁收集關于PyQt5通過信號實現MVC的示例的相關信息資訊供網民參考!
  • 推薦文章
    主站蜘蛛池模板: 日本无遮挡吃奶摸下激烈视频 | 强壮公弄得我次次高潮厨房| 成人午夜大片| 长海县| 热久久亚洲| 怡春院美国十次欧美| 韩国漫画羞羞| 极品华裔白嫩与洋男友| 日韩欧美动漫AV一区二区| 岛国虐乳紧缚媚药调教| 黄无遮挡免费网站视频| 李丽莎大尺度视频观看| 国产 精品一区二区三区| 成人免费韩漫网站无遮羞| 篠田优被公侵犯电影| 亚洲AV欧美AV无码夜夜小说| 韩国高清videoshd| 害羞草研究所| 国产午夜AAA片无码无片久久| 亚洲欧美日韩天堂在线观看| 意大利r级理片在线观看| 欧美最粗又大黑人XXOO| 久久精品国产精品青草色艺| 又大又粗又硬又紧又爽| 丝袜英语老师…好紧在线观看| 少妇做受XXXXⅩ高潮片直播| 精品爆乳爆乳一区二区三区无码av| 公妇借种h| 无遮羞无删减肉动漫在线观看| 影音先锋琪琪| 被20个男人灌了一夜精子| 女人和拘做受A级毛片免费| 国产真实伦露脸| les拉拉嗯啊手太深了| 国精品人妻无码一区二区三区性色| 十部顶级刺激电影国产| 公么吃奶摸下面好舒服| 又硬又粗又黄又爽又大又紧| 亚洲综合二区| 亚洲精品一区二区| 篠田优电影在线观看|