解决QMainWindow下setMouseTracking在指定控件下无响应问题(PyQt5+Qtdesigner)
今天做了一个软件,遇到了这个问题,百度了半天,答案都很模糊,钻研了一番,得到解决
简单介绍下界面:
我要实现的功能之一是光标指向label区域时,不用点击鼠标即可自动记录光标坐标,
通过下面三张图可以看到,这个界面从里到外有label、frame、tabwidget三个控件,
理论上,应该要把控件自身及自身所有父类控件全部写上,外加一个总的self.setMouseTracking(True),实现的代码应该是:
1 def __init__(self): 2 self.ShowLabel.setMouseTracking(True) 3 self.Frame.setMouseTracking(True) 4 self.tabWidget.setMouseTracking(True) 5 self.setMouseTracking(True) 6 def mouseMoveEvent(self, e): 7 pass
但是运行后没有效果,然后查看了ui,可以看到self(MainWindow)下面接着的是centralwidget!而且tabWidget下面的子类先是tab_pic才是Frame,那么再加上它们吧!
1 def __init__(self): 2 self.ShowLabel.setMouseTracking(True) 3 self.Frame.setMouseTracking(True) 4 self.tab_pic.setMouseTracking(True) 5 self.tabWidget.setMouseTracking(True) 6 self.centralwidget.setMouseTracking(True) 7 self.setMouseTracking(True) 8 def mouseMoveEvent(self, e): 9 pass
感觉复杂了一些,但是不妨碍理解,因为tabWidget是翻页的,下面有目录栏(tab_dir)和图像栏(tab_pic),label在图像栏下面,所以要加上tab_pic.setMouseTracking(True)。
而centralwidget比较抽象了,它是布局的时候加上的,覆盖在整个self(QMainWindow)窗口之上,其它控件之下。
接下来继续运行,还是无效,所有看得见的父类控件都加上了,难道还是不行吗。。。。别急,还有检查方法。。。查看控件的父类,
1 print('它的父亲:', self.控件名.parent()) 2 print('它的父亲:', self.控件名.parent().objectName())
第一行表示的是查看它父类,是个直接的对象,有的控件父类不止一个,就是一个列表了,第二行表示查看它父类的名字,因为你.setMouseTracking(True)的话要用到一般要用到控件名字
,检查建议是从label开始,再向外扩展,这样避免了走岔路。
print('它的父亲:', self.ShowLabel.parent().objectName())
没问题,继续向上
print('它的父亲:', self.Frame.parent().objectName())
一脉相承,没问题,继续
print('它的父亲:', self.tab_pic.parent().objectName())
出现了一个奇怪的东西,这就是它tab_pic的老父亲了,之前没把它设置上.setMouseTracking(True),导致中间断代。那就把它加上
由于它的名字没法直接使用,直接用父类对象代替之。
self.tab_pic.parent().setMouseTracking(True)
那么所有的代码就是,测试了之后可以正常运行,有效!!
def __init__(self): self.ShowLabel.setMouseTracking(True) self.Frame.setMouseTracking(True) self.tab_pic.setMouseTracking(True) self.tab_pic.parent().setMouseTracking(True) self.tabWidget.setMouseTracking(True) self.centralwidget.setMouseTracking(True) self.setMouseTracking(True) def mouseMoveEvent(self, e): pass
总结:QMainWindow下对控件设置.setMouseTracking(True),若要其生效,则要将其所有看得见的(容器)或看不见的(逻辑)上的父类都加上.setMouseTracking(True),用self.控件名.parent()引用其对象,self.控件名.parent().objectName()查看其名,当然还有.children()方法可以查看子类,,控件追踪要做到全面,不能断代。