第三篇 -- 界面与逻辑分离的设计方法(多继承方法和单继承方法)

一、多继承方法

  1. 画图Form.ui,生成Form.py

  UI:

  

  Form.py

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file ‘Form.ui‘
#
# Created by: PyQt5 UI code generator 5.13.0
#
# WARNING! All changes made in this file will be lost!

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.label = QtWidgets.QLabel(Form)
        self.label.setGeometry(QtCore.QRect(110, 100, 181, 31))
        font = QtGui.QFont()
        font.setPointSize(12)
        font.setBold(True)
        font.setWeight(75)
        self.label.setFont(font)
        self.label.setObjectName("label")
        self.btnClose = QtWidgets.QPushButton(Form)
        self.btnClose.setGeometry(QtCore.QRect(160, 180, 75, 23))
        self.btnClose.setObjectName("btnClose")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Demo2_2"))
        self.label.setText(_translate("Form", "Hello, by UI Designer"))
        self.btnClose.setText(_translate("Form", "关闭"))

  2. 多继承方法导入界面Form.py

  appMain2.py

# # appMain2.py  多继承方法
"""
多继承方式优缺点:
1. 界面上的组件都成为窗体业务逻辑类QmyWidget的公共属性,外界可以直接访问。优点是访问方便,缺点是过于开放,
    不符合面向对象严格封装的设计思想
2. 界面上的组件与QmyWidget类里新定义的属性混合在一起了,不便于区分。当窗体上的界面组件较多,
    且窗体业务逻辑类里定义的属性也很多时,就难以区分哪个属性是界面上的组件,哪个属性是在业务逻辑类里新定义的,
    这样不利于界面与业务逻辑分离。
"""
import sys
from PyQt5.QtWidgets import QWidget, QApplication
from Form import Ui_Form

class QmyWidget(QWidget, Ui_Form):
    def __init__(self, parent=None):
        super().__init__(parent)   # 调用父类构造函数,创建QWidget窗体

        self.Lab = "多重继承的QmyWidget"   # 新定义的一个变量
        self.setupUi(self)  # self是QWidget窗体,可作为参数传给setupui()
        self.label.setText(self.Lab)

if __name__ == "__main__":
    app = QApplication(sys.argv)  # 创建app
    myWidget = QmyWidget()
    myWidget.show()
    myWidget.btnClose.setText("不关闭了")
    sys.exit(app.exec_())

  3. 多继承解析:

  a. 采用多继承的方式定义了一个类QmyWidget,称这个类为窗体的业务逻辑类,它的父类是QWidget和Ui_Form。

  b. 在这个类的构造函数中,首先用函数super()获取父类,并执行父类的构造函数,代码是super().__init__(parent),在多继承时,使用super()得到的是第一个基类,在这里就是QWidget。所以,执行这条语句后,self就是一个QWidget对象。

  c. 调用setUi()函数创建UI窗体,即self.setupUi(self)。因为QmyWidget的基类包括Ui_Form类,所以可以调用Ui_Form类的setupUi()函数。同时,经过前面调用父类的构造函数,self是一个QWidget对象,可以作为参数传递给setupUi()函数,正好作为各组件的窗体容器。

  d. 通过这样的多继承,Ui_Form类中定义的窗体上的所有界面组件对象就变成了新定义的类QmyWidget的公共属性,可以直接访问这些界面组件。

二、单继承与界面独立封装方法

  1. 同样写一个界面,同多继承一样Form.py

  

  2. 单继承方法导入界面Form.py

  appMain.py 

# # appMain.py 单继承方法,能更好地进行界面与逻辑的分离
import sys
from PyQt5.QtWidgets import QWidget, QApplication
from Form import Ui_Form

class QmyWidget(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)  # 调用父类构造函数,创建QWidget窗体
        self.__ui = Ui_Form()  # 创建UI对象
        self.__ui.setupUi(self)  # 构造UI
        self.Lab = "单继承的QmyWidget"
        self.__ui.label.setText(self.Lab)

    def set_btn_text(self, a_text):
        self.__ui.btnClose.setText(a_text)

if __name__ == "__main__":
    app = QApplication(sys.argv)  # 创建app,用QApplication类
    myWidget = QmyWidget()
    myWidget.show()
    myWidget.set_btn_text("间接设置")
    sys.exit(app.exec_())

  3. 单继承解析

  a. 新定义的窗体业务逻辑类QmyWidget只有一个基类QWidget。

  b. 在QmyWidget的构造函数中,首先调用父类(也就是QWidget)的构造函数,这样self就是一个QWidget对象

  c. 显式地创建了一个Ui_Form类的私有属性self.__ui,即self.__ui = Ui_Form。私有属性self.__ui包含了可视化设计的UI窗体上的所有组件,所以,只有通过self.__ui才可以访问窗体上的组件,包括调用其创建界面组件的setupUi()函数

  注:Python语言的类定义通过命名规则来限定元素对外的可见性,属性或方法名称前有两个下划线表示是私有的,一个下划线表示模块内可见,没有下划线的就是公共的。

  d. 由于self.__ui是QmyWidget类的私有属性,因此在应用程序中创建的QmyWidget对象myWidget不能直接访问myWidget.__ui,也就无法直接访问窗体上的界面组件。为了访问窗体上的组件,可以在QWidget类里定义接口函数,例如set_btn_text()用于设置窗体上按钮的文字。在应用程序里创建QmyWidget对象的实例myWidget,通过调用set_btn_text()函数间接修改界面上按钮的文字,即myWidget.set_btn_text("间接设置")

  4. 单继承特点

  a. 可视化设计的窗体对象被定义为QmyWidget类的一个私有属性self.__ui,在QmyWidget类的内部对窗体上的组件的访问都通过这个属性实现,而外部无法直接访问窗体上的对象,这更符合面向对象封装隔离的设计思想。

  b. 窗体上的组件不会与QmyWidget里定义的属性混淆,例如self.Lab和self.__ui.label,有利于界面与业务逻辑的分离。

  c. 当然,也可以定义界面对象为公共属性,即创建界面对象时用下面的语句:self.ui = Ui_Form(),这里的ui就是个公共属性,在类的外部也可以通过属性ui直接访问界面上的组件

总结:对比多继承方法和单继承方法,可以发现单继承方法更有利于界面与业务逻辑分离。

原文地址:https://www.cnblogs.com/smart-zihan/p/12632705.html

时间: 2024-10-08 03:04:20

第三篇 -- 界面与逻辑分离的设计方法(多继承方法和单继承方法)的相关文章

tkinter的GUI设计:界面与逻辑分离(二)

由于要用到文件对话框和消息对话框,所以先给出下面的列表. py2 与 py3 中 tkinter 的变化: Tkinter → tkinter tkMessageBox → tkinter.messagebox tkColorChooser → tkinter.colorchooser tkFileDialog → tkinter.filedialog tkCommonDialog → tkinter.commondialog tkSimpleDialog → tkinter.simpledia

tkinter的GUI设计:界面与逻辑分离(四)-- 与 matplotlib 结合

有些场合,我们需要对数据可视化.单是靠 tkinter 难度太大,而且做出来的效果不一定理想. 此时,将 tkinter 与 matplotlib 结合,是最好的选择. 知识点: 将 tkinter 与 matplotlib 结合的整个套路是固定的,只需要关心我们的绘图逻辑和程序逻辑即可 import matplotlib matplotlib.use('TkAgg') import numpy as np from matplotlib.backends.backend_tkagg impor

解析大型.NET ERP系统 界面与逻辑分离

Windows Forms程序实现界面与逻辑分离的关键是数据绑定技术(Data Binding),这与微软推出的ASP.NET MVC的原理相同,分离业务代码与界面层,提高系统的可维护性. 数据绑定 Data Binding 数据绑定技术的主要内容:数据源(Data Source),控件(Control),绑定方式(Binding).通过绑定控件,将数据源中的属性绑定到界面控件中,并可以实现双向的数据绑定.当界面控件中的值发生改变时,可以通过数据绑定控件,更新控件绑定的对象,当通过代码直接改变对

PyQt5系列教程(六)如何让界面和逻辑分离

软硬件环境 OS X EI Capitan Python 3.5.1 PyQt 5.5.1 PyCharm 5.0.3 前言 前面的内容我们介绍了利用QtDesigner来设计界面,再通过命令行工具pyuic5将ui文件转换成py源文件.不过由于要响应事件操作,网网会将相应的槽函数写在ui的py文件里,这样,界面和逻辑开发就混合在一起了,每一次的ui更新都会伴随着转换后py文件的修改,想想就知道烦人了.对于多人协作的项目,这样的效率肯定是低下的.本文就来介绍如何将这二者剥离. 实例讲解 设计ui

认识元数据和IL(上) <第三篇>

说在,开篇之前 很早就有说说Metadata(元数据)和IL(中间语言)的想法了,一直在这篇开始才算脚踏实地的对这两个阶级兄弟投去些细关怀,虽然来得没有<第一回:恩怨情仇:is和as>那么迅速,但是Metadata和IL却是绝对重量级的内容,值得我们在任何时间关注,本文就是开始. 1 引言 你可曾想到,我们的C#代码,编译之后究竟为何物?你可曾认知,我们的可执行程序,运行之时的轨迹究竟为哪般?那么,本文通过对Metadata(元数据)和IL(Intermediate Language, 中间语

cocos2d-x 3.2 之 2048 —— 第三篇

***************************************转载请注明出处:http://blog.csdn.net/lttree****************************************** OK,抓紧更新吧. 长话短说,直奔主题,第三篇: --数字块类的创建 数字块是神马? --就是那个,你滑动的数字,还有随机出现的数字. 我们,先创建一个类NumberTiled,继承自Node: NumberTiled.h: #ifndef __test2048_N

三篇文章带你极速入门php(三)之php原生实现登陆注册

看下成果 ps:纯天然h5,绝不添加任何添加剂(css)以及化学成分(js)(<( ̄ ﹌  ̄)我就是喜欢纯天然,不接受任何反驳) 关于本文 用原生的php和html做了一个登陆注册,大概是可以窥见一般php开发的样子了.不过,low的地方区别提前说一下: 这个是多入口,一般程序都是单入口,单入口就是统一通过index.php进入,然后再引入其他文件,调用其代码,多入口就是每次通过不同文件进入(比如一会展示的login.php和register.php) 保留登陆信息用的是session,现在普遍

Python之路【第三篇】:Python基础(二)

Python之路[第三篇]:Python基础(二) 内置函数 一 详细见python文档,猛击这里 文件操作 操作文件时,一般需要经历如下步骤: 打开文件 操作文件 一.打开文件 1 文件句柄 = file('文件路径', '模式') 注:python中打开文件有两种方式,即:open(...) 和  file(...) ,本质上前者在内部会调用后者来进行文件操作,推荐使用 open. 打开文件时,需要指定文件路径和以何等方式打开文件,打开后,即可获取该文件句柄,日后通过此文件句柄对该文件操作.

第三篇:白话tornado源码之请求来了

上一篇<白话tornado源码之待请求阶段>中介绍了tornado框架在客户端请求之前所做的准备(下图1.2部分),本质上就是创建了一个socket服务端,并进行了IP和端口的绑定,但是未执行 socket的accept方法,也就是未获取客户端请求信息. 概述 本篇就来详细介绍tornado服务器(socket服务端)是如何接收用户请求 数据以及如果根据用户请求的URL处理并返回数据,也就是上图的3系列所有步骤,如上图[start]是一个死循环,其中利用epoll监听服务端 socket句柄,