PYQT5/6上窗体堆叠控件被单击时的响应探究

最近练习一个不用pygame等第三方库作一个类似游戏框架界面,用到了大量的QLabel标签控件来加载各渐变图片形成类似角色在动的动画,控件堆叠在一起时对鼠标单击等的先后顺序是什么样的,作了一个简单的示例来验证,即鼠标单击在点位置上有多个控件对象实例时,总是只对堆叠在最上面的一控件触发相关事件或信号,下面的控件不会响应此单击事件。被单击的控件单击事件被触发后可以再发送信号到主窗体,通过主窗体对应响应的槽函数来对堆叠在下面的控件进行处理。

示例PYTHON + QT5码的代码如下:

import sys 	
import PyQt5
from PyQt5 import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5 import QtCore 
######################################################################################
class MyMainFrm(QMainWindow):
    def __init__(self, parent=None):    
        super(MyMainFrm, self).__init__(parent)      
        self.setWindowIcon(QIcon("5G.JPG"))
        self.resize(800,800)
        self.setFixedSize(800,800)
        self.resize(400,300)     #设置了固定尺寸之后,尺寸便不可修改!
        w=25
        h=25
        n=0
        self.labs=[]  #定义标签集列表
        while n<5:  #创建5个标签控件
            s='第'+str(n)+'号标签'
            lab=MyLabel(s,n,self)                           #不论是否用的self变量,lab不会自行消失,此时从下到上的叠加顺序为0,1,2,3,4,此时单击的范围如果在4和0重叠区,并只会触发4标签的信号槽
            lab.setGeometry(5+h*n, 80+h*n, 400, 400)
            lab.setFrameShape(QFrame.Box)
            lab.setToolTip(f'{n}号标签')
            self.labs.append(lab)  #将创建的标签控件加入标签集
            self.labs[n].signal_clicked.connect(self.labClick2)  
            
            #lab.close()  #保留此语句,窗体上不会有任何标签控件,原理没懂,是不是lab被释放了,但内存数据还在,标签集引用的地址self.labs[]还可以正确得到标签对象的全部二进制码
            n+=1
        self.labs[0].close()  #示例,关闭第0号标签.如果循环体中有 lab.close(),此代码也不会报错,调用重载的标签close事件
        self.labs[0].show()   #示例,如果循环体中有 lab.close(),且重载的close()中没有self.deleteLater()代码,此代码还会显示出0号标签,即close并不会真正删除控件循环体内建立的标签
                                    #如果循环体中有 lab.close(),且重载的close()中有self.deleteLater()代码,则此时show()不会再显示出0号标签,但也不报错
        
        self.setTabOrder(self.labs[4],self.labs[0])  #调整TAB顺序对重叠触发用
        self.labs[2].raise_()   #1标签提到重叠最上面,此时从下到上的叠加顺序为1,3,4,0(如果colose没有释放掉还在),2,  即点击的区域如果在2和其他号标签重叠的区域,将会只触发2的信号槽函数,
        self.labs[4].lower()    #4标签提到重叠最下面,此时从下到上的叠加顺序为4,1,3,0,2,即点击的区域如果在4和其他号标签重叠的区域,将会不会触发4标签的信号槽函数,而是其他相对最上面的标签,
                                #但如果0标签在clolse函数中被deleteLater()了,界面中不会出现0标签控件,从下到上的叠加顺序为4,1,2,3

    #主窗体中绑定的同标签关联的信号signal_clicked对应的槽函数,此信号同时发送了一个id的变量参数过来供槽函数labClick1使用
    def labClick2(self,id):
        print(f'后:主窗口中接收到的标签被单击时的槽函数:id={id}标签被单击')  #id变量靠槽函数传递
        self.labs[2].lower() #2标签放在最下,此时从下到上的叠加顺序为2,1,4,0(如果colose没有释放掉还在)或3,即点击的区域如果在0和其他号标签重叠的区域,将会只触发0的信号槽函数,

#重载标签类        
class MyLabel(QLabel):
    signal_clicked = QtCore.pyqtSignal(int)   #自定义标签的信号槽
    #初始化
    def __init__(self,text='',id=0,parent=None):    
        super(QLabel, self).__init__(parent)   
        self.setText(text)   
        self.id=id
        self.signal_clicked.connect(self.labClick1)  
    #鼠标按下事件重载   
    def mousePressEvent(self, event):
        #print(f'当前鼠标压下坐标:x={event.pos().x()},y={event.pos().y()}')
        # 鼠标左键按下
        if event.button() == Qt.LeftButton:
            self.signal_clicked.emit(self.id)   #在DEMO标签上按下鼠标键后,发送此信号出去,主窗体接收此信号,调用对应定义的槽函数响应
        
    #重载标签类中的同单击事件绑定的本类槽函数,即单击标签后
    def labClick1(self):
        print(f'先:标签类中接收到的标签被单击时的槽函数:id={self.id}标签被单击')   #标签实例化对象id值为自有属性,可不必使用槽来接收变量,当然也可以用槽变量
    
    def close(self):
        print('重载标签关闭函数')
        super().close()          #调用父类的close,也不会影响在show()后又被显出来,表示close并没完全释放控件窗体
        self.deleteLater()      #加了此代码,将会彻底释放被创建的窗体,上面因0号标签被close了,故show时不会再显示0号标签,但奇怪的是self.labs[0].show()   self.labs[0].raise_()等也不会报错
                                #如此语句存在,主窗体循环体中调用了lab.close(),界面上将不会出现任何标签控件,自已测试效果
    
if __name__=="__main__":  
    app = QApplication(sys.argv)  
    myWin = MyMainFrm()  
    myWin.show()  
    sys.exit(app.exec())  

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
PyQt5中的堆显示是指将多个件堆在一起,只显示其中的一个件,其他件被隐藏。当需要切换显示的,只需要更改当前显示的件即可。 PyQt5中实现堆显示可以使用QStackedWidget件。该件可以包含多个子件,但只会显示其中的一个子件。可以使用setCurrentIndex()方法来设置当前显示的子件的索引,或者使用setCurrentWidget()方法来设置当前显示的子件。 以下是一个简单的例子,演示如何使用QStackedWidget实现堆显示: ```python import sys from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QStackedWidget, QPushButton class StackedExample(QWidget): def __init__(self): super().__init__() self.initUI() def initUI(self): # 创建QStackedWidget件,并添加两个子件 self.stack = QStackedWidget(self) self.stack.addWidget(self.createWidget('Widget 1')) self.stack.addWidget(self.createWidget('Widget 2')) # 创建两个按钮,用于切换显示的子件 btn1 = QPushButton('Show widget 1', self) btn1.clicked.connect(lambda:self.stack.setCurrentIndex(0)) btn2 = QPushButton('Show widget 2', self) btn2.clicked.connect(lambda:self.stack.setCurrentIndex(1)) # 创建垂直布局,并将按钮和QStackedWidget添加进布局中 vbox = QVBoxLayout() vbox.addWidget(btn1) vbox.addWidget(btn2) vbox.addWidget(self.stack) self.setLayout(vbox) self.setWindowTitle('Stacked Widget Example') self.show() def createWidget(self, text): # 创建一个QWidget件,并在上面添加一些文本 widget = QWidget(self) widget.setStyleSheet('background-color: yellow') layout = QVBoxLayout(widget) layout.addWidget(QPushButton('Button 1', widget)) layout.addWidget(QPushButton('Button 2', widget)) layout.addWidget(QPushButton('Button 3', widget)) layout.addWidget(QPushButton('Button 4', widget)) layout.addWidget(QPushButton('Button 5', widget)) layout.addWidget(QPushButton('Button 6', widget)) layout.addWidget(QPushButton('Button 7', widget)) layout.addWidget(QPushButton('Button 8', widget)) layout.addWidget(QPushButton('Button 9', widget)) layout.addWidget(QPushButton('Button 10', widget)) layout.addWidget(QPushButton('Button 11', widget)) layout.addWidget(QPushButton('Button 12', widget)) layout.addWidget(QPushButton('Button 13', widget)) layout.addWidget(QPushButton('Button 14', widget)) layout.addWidget(QPushButton('Button 15', widget)) layout.addWidget(QPushButton('Button 16', widget)) layout.addWidget(QPushButton('Button 17', widget)) layout.addWidget(QPushButton('Button 18', widget)) layout.addWidget(QPushButton('Button 19', widget)) layout.addWidget(QPushButton('Button 20', widget)) return widget if __name__ == '__main__': app = QApplication(sys.argv) ex = StackedExample() sys.exit(app.exec_()) ``` 在上面的例子中,我们创建了一个QStackedWidget件,并添加了两个QWidget子件。然后创建了两个按钮,用于切换显示的子件。最后,将这些件放在垂直布局中,并将其设置为口的主布局。运行程序后,点击不同的按钮即可切换显示的子件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mr_LuoWei2009

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值