スポンサーサイト

    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    QtでDesktopの情報をゲットする

     Qtにはデスクトップの情報を取得するための機能が盛り込まれてます。これらを使用すれば、例えばウィンドウをデスクトップの中心に必ず表示するようにしたり、ウィンドウを表示する時に画面の端を超えないようにしたりと、様々な処理が出来るようになりますな!


     デスクトップの情報自体は
    QtGui.qApp.desktop()
    で返ってくるQDesktopWiedgetに格納されています。

    それでは色々情報を取ってみよう~!!



    ■デスクトップのサイズを取得する!
    まずは基本から。
    # -*- coding:utf-8 -*-
    import sys
    from PyQt4 import QtGui
    app     = QtGui.QApplication( sys.argv )
    desktop = QtGui.qApp.desktop()
    
    width   = desktop.width()	# デスクトップの幅
    height  = desktop.height()	# デスクトップの高さ
    print( u'デスクトップの大きさ : %s x %s' % ( width, height ) )
    
     これでデスクトップの幅と高さを取得できました。これだけでも色々と使い道がありますよね!



    ■タスクバーはノーカンにしたいあなたに
     上の例はあくまでデスクトップのサイズです。しかしWindowsやMacなど各種OSにはタスクバーやメニューバーがあり、基本的にこれらは最前面に出ているため事実上この領域は使えません。
     しかもWindowsではタスクバーを自由に動かせたり幅を変えられるので、決め打ちで値を入れてしまうとユーザーによってはちゃんと思ったような挙動にはならなかったりします。
     そこで、タスクバーなどを除いた領域のみを返すようにしてみましょう!
    # -*- coding:utf-8 -*-
    import sys
    from PyQt4 import QtGui
    app     = QtGui.QApplication( sys.argv )
    desktop = QtGui.qApp.desktop()
    
    drect   = desktop.availableGeometry()
    print( u'利用可能デスクトップの位置・大きさ : %s' % drect )
    
     利用可能な領域がQRect形式(開始位置・大きさを格納したオブジェクト)で返ってきます。
     これで作成したウィンドウがタスクバーの影に隠れちゃうようことを防ぐ事ができますぜ!



    ■マルチモニターだけど、作成したウィンドウはどこのモニタにいるん?
     そんな場合は QDesktopWidget.screenNumber()を使うべし!
    screenNumberメソッドは2種類の引数をとります。一つはQWidgetのインスタンス、もう一つはQPoint(座標ですな)。
    QWidgetを引数として与えてやれば、そのウィジットがどのモニタに居るかを0ベースの番号で教えてくれます。
    QPointを与えてやれば、その座標がどのモニタに位置するのかを教えてくれます。素晴らしい!
     まずはウィジットを追従するタイプのサンプルを。
    # -*- coding:utf-8 -*-
    import sys
    import time
    from PyQt4 import QtGui, QtCore
    
    class ScreenObserver( QtCore.QThread ):
    	screenChanged = QtCore.pyqtSignal( int )
    	def __init__( self, widget ):
    		super( ScreenObserver, self ).__init__( widget )
    		self.widget        = widget
    
    		self.desktop       = QtGui.qApp.desktop()
    		self.currentScreen = self.desktop.screenNumber( widget )
    
    	def run( self ):
    		while( True ):
    			time.sleep( 0.05 )
    
    			# 登録されたWidgetがいるモニタ番号を取得する。
    			screenNumber = self.desktop.screenNumber( self.widget )
    			if screenNumber == self.currentScreen:
    				continue
    			self.currentScreen = screenNumber
    			self.screenChanged.emit( screenNumber )
    
    
    
    class Window( QtGui.QWidget ):
    	def __init__( self, parent=None ):
    		super( Window, self ).__init__( parent )
    		self.resize( 200, 200 )
    
    		layout     = QtGui.QVBoxLayout( self )
    		self.label = QtGui.QLabel( '0' )
    		self.label.setStyleSheet(
    			'font-family:arial black; font-size:128px'
    		)
    		
    		layout.addWidget( self.label )
    		layout.setAlignment( self.label, QtCore.Qt.AlignCenter )
    
    		thread = ScreenObserver( self )
    		thread.screenChanged.connect( self.update )
    		thread.start()
    
    	def update( self, int ):
    		self.label.setText( str( int ) )
    
    
    if __name__ == '__main__':
    	app = QtGui.QApplication( sys.argv )
    	win = Window()
    	win.show()
    	
    	sys.exit( app.exec_() )
    
     ウィンドウを動かしてモニタをまたぐと、そのウィンドウが移動した先のモニタ番号を表示します。

     普通にウィンドウを作成し、それとは別に場所監視用スレッドを作成。
     スレッド内のループ処理部分で、20行目部分でウィジットのモニタ位置を取得し、番号が変わっている場合にウィンドウ内の文字を変更するようにしてます。
     スレッドに関する処理はQThreadでストレスフルな生活を (並行処理って素敵だよネ)をご覧あれ。



     こちらはマウスカーソルの位置からモニタ番号を特定するバージョン。
    # -*- coding:utf-8 -*-
    import sys
    import time
    from PyQt4 import QtGui, QtCore
    
    class CursorObserver( QtCore.QThread ):
    	screenChanged = QtCore.pyqtSignal( int )
    	def __init__( self, widget ):
    		super( CursorObserver, self ).__init__( widget )
    		self.desktop       = QtGui.qApp.desktop()
    		self.currentScreen = self.desktop.screenNumber( QtGui.QCursor().pos() )
    
    	def run( self ):
    		while( True ):
    			time.sleep( 0.05 )
    
    			# マウスカーソルがいるモニタ番号を取得する。
    			screenNumber = self.desktop.screenNumber( QtGui.QCursor().pos() )
    			if screenNumber == self.currentScreen:
    				continue
    			self.currentScreen = screenNumber
    			self.screenChanged.emit( screenNumber )
    
    
    
    class Window( QtGui.QWidget ):
    	def __init__( self, parent=None ):
    		super( Window, self ).__init__( parent )
    		self.resize( 200, 200 )
    
    		layout     = QtGui.QVBoxLayout( self )
    		self.label = QtGui.QLabel( '0' )
    		self.label.setStyleSheet(
    			'font-family:arial black; font-size:128px'
    		)
    		
    		layout.addWidget( self.label )
    		layout.setAlignment( self.label, QtCore.Qt.AlignCenter )
    
    		thread = CursorObserver( self )
    		thread.screenChanged.connect( self.update )
    		thread.start()
    
    	def update( self, int ):
    		self.label.setText( str( int ) )
    
    
    if __name__ == '__main__':
    	app = QtGui.QApplication( sys.argv )
    	win = Window()
    	win.show()
    	
    	sys.exit( app.exec_() )
    
     スレッドのクラスをCursorObserverに変更。11行目と18行目でマウスカーソルの位置からモニタ番号を割り出してます。それ以外はほとんど一緒~。


     また、上記で取得した番号をQDesktopWidget.availableGeometry()に渡してやれば、そのモニタの利用可能エリアを特定できます。
    QtGui.qApp.desktop().availableGeometry(
        QtGui.qApp.desktop().screenNumber( QtGui.QCursor().pos() )
    )
    
    変数に分けずに一括で書いたから糞長くなってしまった。
     こんな感じで、これらを駆使するとデスクトップとの位置関係にまつわる様々な挙動を制御できるようになりますね!!
     色々情報取ってこれて素敵ング!!
     最後にデスクトップの情報を色々拾ってくるサンプルで終わりにします
    # -*- coding:utf-8 -*-
    import sys
    import time
    from PyQt4 import QtGui, QtCore
    
    class CursorObserver( QtCore.QThread ):
    	cursorScreenChanged = QtCore.pyqtSignal( int )
    	def __init__( self, widget ):
    		super( CursorObserver, self ).__init__( widget )
    		self.desktop       = QtGui.qApp.desktop()
    		self.currentCursorScreen = -1
    
    	def run( self ):
    		while( True ):
    			time.sleep( 0.05 )
    			# マウスカーソルがいるモニタ番号を取得する。
    			screenNumber = self.desktop.screenNumber( QtGui.QCursor().pos() )
    			if screenNumber != self.currentCursorScreen:
    				self.currentCursorScreen = screenNumber
    				self.cursorScreenChanged.emit( screenNumber )
    
    
    
    class Window( QtGui.QWidget ):
    	def __init__( self, parent=None ):
    		super( Window, self ).__init__( parent )
    		self.resize( 320, 320 )
    
    		# デスクトップの情報を集めてくる。=====================================
    		desktop    = QtGui.qApp.desktop()
    		dWidth     = desktop.width()		# デスクトップ幅の取得
    		dHeight    = desktop.height()		# デスクトップ高の取得
    		numberOfD  = desktop.screenCount()	# マルチデスクトップの数を取得
    		# =====================================================================
    
    		layout     = QtGui.QVBoxLayout( self )
    
    		# カーソルのデスクトップ位置を知らせるラベル。=========================
    		self.cursorLabel = QtGui.QLabel( '0' )
    		cursorGroup      = QtGui.QGroupBox( u'カーソル位置' )
    		cursorLayout     = QtGui.QVBoxLayout( cursorGroup )
    		self.cursorLabel.setStyleSheet(
    			'font-family:arial black; font-size:128px'
    		)
    		cursorLayout.addWidget( self.cursorLabel )
    		cursorLayout.setAlignment( self.cursorLabel, QtCore.Qt.AlignCenter )
    		layout.addWidget( cursorGroup )
    		# =====================================================================
    
    		# デスクトップの情報を表示するUI。=====================================
    		infoGroup  = QtGui.QGroupBox( u'デスクトップ情報' )
    		infoLayout = QtGui.QVBoxLayout( infoGroup )
    		dSizeLabel = QtGui.QLabel( u'デスクトップの大きさ : %s × %s' % (
    				dWidth, dHeight
    			)
    		)
    		dNumLabel  = QtGui.QLabel( u'モニタの数 : %s' % numberOfD )
    		infoLayout.addWidget( dSizeLabel )
    		infoLayout.addWidget( dNumLabel )
    		# =====================================================================
    		
    		layout.addWidget( infoGroup )
    
    		thread = CursorObserver( self )
    		thread.cursorScreenChanged.connect( self.update )
    		thread.start()
    
    	def update( self, int ):
    		self.cursorLabel.setText( str( int ) )
    
    		# 現在マウスカーソルがいるモニタの利用可能エリアの情報を取得。
    		desktop = QtGui.qApp.desktop()
    		dRect   = desktop.availableGeometry( int )
    
    		# 利用可能エリアの中心にこのウィンドウを移動する。
    		rect    = self.rect()
    		rect.moveCenter( dRect.center() )
    		self.setGeometry( rect )
    
    
    if __name__ == '__main__':
    	app = QtGui.QApplication( sys.argv )
    	win = Window()
    	win.show()
    	
    	sys.exit( app.exec_() )
    
    スポンサーサイト

    コメントの投稿

    非公開コメント

    プロフィール

    Eske

    Author:Eske
    萌えイラストレーターを目指す3DCGイラストレーター。
    現在ポケモンカードゲーム、ガンダムトライエイジ、ガンダムコンクエスト、妖怪ウォッチとりつきカードゲームなどで3DCGを使用したイラストレーターとして参加中。

    主にここでは日々気づいたメモなんかを残してます。
    イラストのお仕事も受け付けております。ココからアクセスできますので、お気軽にご相談下さい。

    最新記事
    最新コメント
    カテゴリ
    最新トラックバック
    月別アーカイブ
    検索フォーム
    リンク
    QRコード
    QR
    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。