フォーカスが外れると消えるウインドウを作る方法!!




takkun
どうも!たっくんです!
Animojiの為だけにiPhoneXがほしい!

Qt(PySide/PyQt)で作成したウインドウが、「アクティブでなく立った時」「フォーカスが外れた時」にウインドウを消したい!と思ったことはございませんか!?

今回は、そんな方法をご紹介したいと思いまーす(`・ω・´)ゞ

クラスの骨格

基底クラスはなんでもいいのですが、今回は「QDialog」をベース作成したいと思います!

from PySide import QtCore, QtGui

class MainWindow(QtGui.QDialog):
	def __init__(self, *args, **kwargs):
		super(MainWindow, self).__init__(*args, **kwargs)

ウインドウのフラグの設定

せっかくなので、最近流行り?のフレームレスウインドウにしたいと思います(*´ω`*)b

from PySide import QtCore, QtGui

class MainWindow(QtGui.QDialog):
	def __init__(self, *args, **kwargs):
		super(MainWindow, self).__init__(*args, **kwargs)
		self.setWindowFlags(QtCore.Qt.Tool|QtCore.Qt.FramelessWindowHint)

ウインドウを閉じる仕組み

状態に応じてウインドウを閉じる仕組みを「eventFilter」を使ってやりたいと思います!「eventFilter」は、「installEventFilter」を使って登録しないと機能しないのでご注意ください!

from PySide import QtCore, QtGui

class MainWindow(QtGui.QDialog):
	def __init__(self, *args, **kwargs):
		super(MainWindow, self).__init__(*args, **kwargs)
		self.setWindowFlags(QtCore.Qt.Tool|QtCore.Qt.FramelessWindowHint)
		self.installEventFilter(self)# eventFilterの登録
		
	def eventFilter(self, object, event):
		# アクティブでなくなった時
		if event.type() == QtCore.QEvent.WindowDeactivate:
			self.close()
			
		# フォーカスが外れた時
		elif event.type() == QtCore.QEvent.FocusOut:
			self.close()
			
		# それ以外は、通常のeventFilterを実行
		else:
			return super(MainWindow, self).eventFilter(object, event)

実験!

以下のコードで、うまく動作するか試してみます!ウインドウを表示する時に、「activeWindow」を実行しないとウインドウがうまく閉じないのでご注意ください!

from PySide import QtCore, QtGui
from maya import OpenMayaUI
import shiboken

class MainWindow(QtGui.QDialog):
	def __init__(self, *args, **kwargs):
		super(MainWindow, self).__init__(*args, **kwargs)
		self.setWindowFlags(QtCore.Qt.Tool|QtCore.Qt.FramelessWindowHint)
		self.installEventFilter(self)
		
	def eventFilter(self, object, event):
		if event.type() == QtCore.QEvent.WindowDeactivate:
			self.close()
		elif event.type() == QtCore.QEvent.FocusOut:
			self.close()
		else:
			return super(MainWindow, self).eventFilter(object, event)

def getMayaWindow():
	ptr = OpenMayaUI.MQtUtil.mainWindow()
	widget = shiboken.wrapInstance(long(ptr), QtGui.QMainWindow)
	return widget
	
w = MainWindow(getMayaWindow())
w.show()
w.activateWindow()# これを忘れると、うまく閉じる事ができない!

こんな感じで、動作することができましたっ!!素早く表示できるようにしてあげれば、便利そうですね(`・ω・´)ゞ