qt里closeevent是私有还是公有

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了qt里closeevent是私有还是公有相关的知识,希望对你有一定的参考价值。

二进制兼容
如果程序从一个以前版本的库动态链接到新版本的库之后,能够继续正常运行,而不需要重新编译,那么我们就说这个库是二进制兼容的。

如果不能保证库的二进制兼容性,就意味着每次发布库的新版本时,依赖该库的所有程序都必须重新编译才能正常运行。

2、公有类、私有类

是解决信息隐藏的问题的,发布库文件时只提供公有类的头文件而不必提供私有类的头文件,从而隐藏掉一些不想公开的内容。

如果修改的内容是私有类里面的,那么重新编译库以后,对外的公有类并没有发生变化,从而达到二进制兼容的目的。

因此这样设计类的目的至少有两个:

(1)信息隐藏

(2)二进制兼容

你不应该把这样的 private class 放在你的类的同一个头文件中,因为这样做的话就没有意义了。常见做法是,定义一个 private 的头文件,例如使用 myclass_p.h 的命名方式(这也是 Qt 的命名方式)。并且记住,不要把 private 头文件放到你发布的 include 下面!因为这不是你发布的一部分,它们是私有的。

或者把私有类定义在公有类的cpp文件中。

一般是将公有类中的private成员放在私有类中。

3、Q_Q、Q_D

Q_Q是私有类访问公有类的方法。

Q_D是公有类访问私有类的方法。

 
参考技术A 二、私有信号的作用
私有信号只能被响应,不能被用户代码来发射(emit)。这是一种对某些信号的权限控制,也就是用户代码没有权力“发号施令”,只能由Qt的类来发射,防止信号被”仿造“。
三、是否可以用在我们的代码中?
1. 首先我的想法是用private signals,测试了一下,编译不过。
2. 首先观察Qt是怎么实现私有信号的。如下图QThread的头文件中,私有信号在声明时,添加了一个QPrivateSignal作为输入参数。
QPrivateSignal是什么呢?QPrivateSignal是在Q_OBJECT宏中定义的一个空的结构体,如下图:
这是一个私有空结构体。外部代码或者子类代码中都无法访问此结构体,如此一来就保证了信号函数是私有的。
连接槽时,槽是可以直接忽略信号的参数的。所以槽可以写成无参函数。
综上,如果我们要自己实现私有信号,只要加一个QPrivateSignal作为信号参数即可。
四、最后
这是目前个人对私有信号的初步认识,要在实践中不断加深对它的认识和运用。
参考技术B qt里closeevent是私有还是公有
私有
这是一个私有空结构体。外部代码或者子类代码中都无法访问此结构体,如此一来就保证了信号函数是私有的。
参考技术C Qt 4版本(4.8.7)下是「保护」(protected),Qt 5版本(5.12.1)下是「公有」(public)。
  Qt没有改造编译器,语法依然是C++语法。所谓的信号(signals)和槽(slots)依然在C++语法范围内,并没有做出编译器意义上的扩展。信号和槽本质上还是某个类的成员函数。
参考技术D public在组件外可以被反射调用。除了想开放的接口用public,全都用private。后者中想被子类继承的改为protected。

Qt Designer PyQt5 覆盖 CloseEvent 子窗口不起作用

【中文标题】Qt Designer PyQt5 覆盖 CloseEvent 子窗口不起作用【英文标题】:Qt Designer PyQt5 overwrite CloseEvent child window don't work 【发布时间】:2017-05-17 16:58:19 【问题描述】:

我在 QtDesigner 中设计了三个窗口。主窗口使用按钮调用两个子窗口。如果我关闭主窗口,子窗口也会关闭,我通过覆盖主窗口中的 closeEvent 来做到这一点。我需要在子窗口的 closeEvent 中实现一些东西,所以我覆盖了子类的 closeEvent 但它什么也没做。请帮忙。

Qt Designer中制作的主窗口类

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_ventanaPrincipal(object):
    def setupUi(self, ventanaPrincipal):
        ventanaPrincipal.setObjectName("ventanaPrincipal")
        ventanaPrincipal.resize(267, 238)
        self.centralWidget = QtWidgets.QWidget(ventanaPrincipal)
        self.centralWidget.setObjectName("centralWidget")
        self.buttonVentana1 = QtWidgets.QPushButton(self.centralWidget)
        self.buttonVentana1.setGeometry(QtCore.QRect(60, 30, 141, 25))
        self.buttonVentana1.setObjectName("buttonVentana1")
        self.buttonVentana2 = QtWidgets.QPushButton(self.centralWidget)
        self.buttonVentana2.setGeometry(QtCore.QRect(60, 80, 141, 25))
        self.buttonVentana2.setObjectName("buttonVentana2")
        ventanaPrincipal.setCentralWidget(self.centralWidget)
        self.menuBar = QtWidgets.QMenuBar(ventanaPrincipal)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 267, 22))
        self.menuBar.setObjectName("menuBar")
        ventanaPrincipal.setMenuBar(self.menuBar)
        self.mainToolBar = QtWidgets.QToolBar(ventanaPrincipal)
        self.mainToolBar.setObjectName("mainToolBar")
        ventanaPrincipal.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
        self.statusBar = QtWidgets.QStatusBar(ventanaPrincipal)
        self.statusBar.setObjectName("statusBar")
        ventanaPrincipal.setStatusBar(self.statusBar)

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

    def retranslateUi(self, ventanaPrincipal):
        _translate = QtCore.QCoreApplication.translate
        ventanaPrincipal.setWindowTitle(_translate("ventanaPrincipal", "ventanaPrincipal"))
        self.buttonVentana1.setText(_translate("ventanaPrincipal", "Ventana 1"))
        self.buttonVentana2.setText(_translate("ventanaPrincipal", "Ventana 2"))

第一个子窗口的类

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_subVen1(object):
    def setupUi(self, subVen1):
        subVen1.setObjectName("subVen1")
        subVen1.resize(320, 347)
        self.label = QtWidgets.QLabel(subVen1)
        self.label.setGeometry(QtCore.QRect(40, 20, 141, 17))
        self.label.setObjectName("label")
        self.listWidget = QtWidgets.QListWidget(subVen1)
        self.listWidget.setGeometry(QtCore.QRect(20, 60, 256, 192))
        self.listWidget.setObjectName("listWidget")

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

    def retranslateUi(self, subVen1):
        _translate = QtCore.QCoreApplication.translate
        subVen1.setWindowTitle(_translate("subVen1", "Form"))
        self.label.setText(_translate("subVen1", "MIAU MIAU"))

第二个子窗口的类

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_subVen2(object):
    def setupUi(self, subVen2):
        subVen2.setObjectName("subVen2")
        subVen2.resize(320, 304)
        self.listView = QtWidgets.QListView(subVen2)
        self.listView.setGeometry(QtCore.QRect(40, 60, 256, 192))
        self.listView.setObjectName("listView")
        self.label = QtWidgets.QLabel(subVen2)
        self.label.setGeometry(QtCore.QRect(80, 20, 121, 17))
        self.label.setObjectName("label")

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

    def retranslateUi(self, subVen2):
        _translate = QtCore.QCoreApplication.translate
        subVen2.setWindowTitle(_translate("subVen2", "Form"))
        self.label.setText(_translate("subVen2", "Guau Guau"))

调用其他三个的文件。

import sys
#import classes-----------------------
from HMIs.ventanaprincipal import Ui_ventanaPrincipal, QtWidgets
from HMIs.subventana1 import Ui_subVen1
from HMIs.subventana2 import Ui_subVen2
# hijaSub1 inherits the first child window class made by the QtDesigner
#override child closeEvent
class hijaSub1(Ui_subVen1):
   def closeEvent(self, event):
      print("X is clicked")


class multiVen(QtWidgets.QMainWindow):
    def __init__(self,parent=None):
        QtWidgets.QWidget.__init__(self,parent=None)
        self.ui =Ui_ventanaPrincipal()
        self.ui.setupUi(self)
        self.subV1=QtWidgets.QWidget()
        self.subV2=QtWidgets.QWidget()
        #Conect signals whith slots--------------------
        self.ui.buttonVentana1.clicked.connect(self.muestraVentana1)
        self.ui.buttonVentana2.clicked.connect(self.muestraVentana2)
    # slots-----------------------------------------
    def muestraVentana1(self):
        self.wid1=hijaSub1()
        self.wid1.setupUi(self.subV1)
        self.subV1.show() 

    def muestraVentana2(self):
        self.wid2=Ui_subVen2()
        self.wid2.setupUi(self.subV2)
        self.subV2.show()
#Close all windows whith X button of main window
#override main closeEvent        
    def closeEvent(self, event):
        self.subV1.close()
        self.subV2.close()
        event.accept()


if __name__=="__main__":
    app=0
    app=QtWidgets.QApplication(sys.argv)
    myapp=multiVen()
    myapp.show()
    sys.exit(app.exec_())

【问题讨论】:

【参考方案1】:

closeEvent 方法具有继承自 QWidget 的类,在这种情况下,子类 Sub1Ui_subVen1Ui_subVen2 继承自对象,而不是继承自 QWidget

如果要在 windows 中实现closeEvent,请创建一个使用窗口视图 (Ui_xxx) 并继承自 QWidget 的类。

class hijaSub1(QtWidgets.QWidget, Ui_subVen1):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent=parent)
        self.setupUi(self)

    def closeEvent(self, event):
        print("X is clicked: hijaSub1")

class hijaSub2(QtWidgets.QWidget, Ui_subVen2):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent=parent)
        self.setupUi(self)

    def closeEvent(self, event):
        print("X is clicked: hijaSub2")

class multiVen(QtWidgets.QMainWindow):
    def __init__(self,parent=None):
        QtWidgets.QWidget.__init__(self,parent=None)
        self.ui =Ui_ventanaPrincipal()
        self.ui.setupUi(self)
        self.subV1=hijaSub1()
        self.subV2=hijaSub2()
        #Conect signals whith slots--------------------
        self.ui.buttonVentana1.clicked.connect(self.muestraVentana1)
        self.ui.buttonVentana2.clicked.connect(self.muestraVentana2)
    # slots-----------------------------------------
    def muestraVentana1(self):
        self.subV1.show() 

    def muestraVentana2(self):
        self.subV2.show()
#Close all windows whith X button of main window
#override main closeEvent        
    def closeEvent(self, event):
        self.subV1.close()
        self.subV2.close()
        event.accept()


if __name__=="__main__":
    import sys
    app=0
    app=QtWidgets.QApplication(sys.argv)
    myapp=multiVen()
    myapp.show()
    sys.exit(app.exec_())

【讨论】:

以上是关于qt里closeevent是私有还是公有的主要内容,如果未能解决你的问题,请参考以下文章

对于金融企业来说,是私有云好还是混合云更好呢?

公有链私有链和联盟链到底有何区别?

类:属性方法的私有公有详解

经典网络还是VPC,开发者作何选择?

区块链技术公司谈并不是所有手机都叫区块链手机

公有云与私有云的概念差别在哪