2022年07月04日

Pyside2を使ったカスタムUI modo15 その36

前回は「QStyledItemDelegate」を使ってセルをダブルクリックしてファイルダイアログから選択した画像ファイルセルに表示するようにしてみた。

今回は画像がセットされたセルにマウスポインタをあわせるとその画像ファイルのパスがツールチップに表示されるようにしてみた。

下がそのプログラム。 「MyStyledItemDelegate」を生成する時に「parent」パラメータとして「tableWidget」オブジェクトを渡しているので「MyStyledItemDelegate」の中から「parent()」メソッドでアクセスできる。そこで「index」の「row()」と「column()」を使って画像ファイルがセットされるセルの位置を特定して、「item()」メソッドでセルに割り当てられた「QTableWidgetItem」オブジェクトを取得して、「setToolTip()」メソッドでアイテムのツールチップをセットしている。

import lx
import lxu
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

class MyStyledItemDelegate(QStyledItemDelegate):
	
	def __init__(self, parent=None):
		super(MyStyledItemDelegate, self).__init__(parent)
		
	def createEditor(self,parent,option,index):
		editor = QFileDialog()
		editor.setFileMode(QFileDialog.ExistingFile)
		editor.setNameFilter("Images (*.png *.jpg)")
		return editor
		
	def setModelData(self,editor, model,index):
  		fileNames = editor.selectedFiles()
		if len(fileNames) >=1 :
			model.setData(index,fileNames[0])
			item = self.parent().item(index.row(),index.column())
			item.setToolTip(fileNames[0])

			return True
		else:
			return False
			
	def paint(self,painter, option, index):
		cellrect = option.rect
		file = index.data(Qt.DisplayRole)
		if file != None :
			image = QImage(file)
			if image :
				imagesize = image.size()
				aspect = imagesize.width()/imagesize.height()
				width = cellrect.height()*aspect
				if width > cellrect.width():
					height = cellrect.width() / aspect
					y = (cellrect.height() - height)/2
					cellrect.setTop(cellrect.top()+y)
					cellrect.setHeight(height)
				else:
					cellrect.setWidth(width)
				painter.drawImage(cellrect, image)
		
class MyDialog(QDialog):
	def __init__(self,parent=None):
		super(MyDialog,self).__init__(parent)
		
		self.tableWidget = QTableWidget(self)
		self.tableWidget.setColumnCount(1)
		self.tableWidget.setRowCount(2)
		self.tableWidget.setItem(0, 0, QTableWidgetItem())
		self.tableWidget.setItem(0, 1, QTableWidgetItem())
		self.tableWidget.setGeometry(QRect(10, 10, 300, 200))
		view = self.tableWidget
		delegate = MyStyledItemDelegate(view)
		view.setItemDelegate(delegate)
		self.resize(320, 230)
		
w = MyDialog()
w.show()

これが実行結果。このようにマウスカーソルをあわせたセルのファイルパスが表示される。

fig 1

続きはまた次回。



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG

2022年06月27日

Pyside2を使ったカスタムUI modo15 その35

前回は「QStyledItemDelegate」を使ってセルをダブルクリックしてファイルダイアログを出して選択したファイルパスをセルにセット出来るようにしてみた。

今回はそれを使ってセルに画像を表示するようにしてみた。

import lx
import lxu
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

class MyStyledItemDelegate(QStyledItemDelegate):
	
	def __init__(self, parent=None):
		super(MyStyledItemDelegate, self).__init__(parent)
		
	def createEditor(self,parent,option,index):
		editor = QFileDialog()
		editor.setFileMode(QFileDialog.ExistingFile)
		editor.setNameFilter("Images (*.png *.jpg)")
		return editor
		
	def setModelData(self,editor, model,index):
  		fileNames = editor.selectedFiles()
		if len(fileNames) >=1 :
			model.setData(index,fileNames[0])
			return True
		else:
			return False
			
	def paint(self,painter, option, index):
		cellrect = option.rect
		file = index.data(Qt.DisplayRole)
		if file != None :
			image = QImage(file)
			if image :
				imagesize = image.size()
				aspect = imagesize.width()/imagesize.height()
				width = cellrect.height()*aspect
				if width > cellrect.width():
					height = cellrect.width() / aspect
					y = (cellrect.height() - height)/2
					cellrect.setTop(cellrect.top()+y)
					cellrect.setHeight(height)
				else:
					cellrect.setWidth(width)
				painter.drawImage(cellrect, image)
		
class MyDialog(QDialog):
	def __init__(self,parent=None):
		super(MyDialog,self).__init__(parent)
		
		self.tableWidget = QTableWidget(self)
		self.tableWidget.setColumnCount(1)
		self.tableWidget.setRowCount(2)
		
		__qtablewidgetitem1 = QTableWidgetItem()
		self.tableWidget.setItem(0, 0, __qtablewidgetitem1)
		__qtablewidgetitem2 = QTableWidgetItem()
		self.tableWidget.setItem(0, 1, __qtablewidgetitem2)
		self.tableWidget.setGeometry(QRect(10, 10, 300, 200))
		view = self.tableWidget
		delegate = MyStyledItemDelegate(view)
		view.setItemDelegate(delegate)
		self.resize(320, 230)
		
w = MyDialog()
w.show()

セルのサイズは「option.rect」から取得し、セルにセットされたファイルパスは「index.data(Qt.DisplayRole)」から取得している。あとはファイルパスから「QImage」を生成して縦横比を計算してその比率を壊さないようにセルに収まるようにスケーリングするようにしてみた。

これが実行結果。

fig 1

続きはまた次回。



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG

2022年06月20日

Pyside2を使ったカスタムUI modo15 その34

今回はデリゲートの仕組みを使って「QTableWidget」のセルの値をファイルダイアログを使って割り当ててみることをしてみた。前回の場合は割り当てたエディタが返す値を加工してテーブルデータとしてセットする必要が無かったけど、今回のファイルについてはその処理が必要になる。それを担うのが「setModelData()」メソッドで、これを上書きしてエディタが戻して来た値をモデルにセットする。

下がそのプログラムだ。

import lx
import lxu
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

class MyStyledItemDelegate(QStyledItemDelegate):
	
	def __init__(self, parent=None):
		super(MyStyledItemDelegate, self).__init__(parent)
		
	def createEditor(self,parent,option,index):
		editor = QFileDialog()
		editor.setFileMode(QFileDialog.ExistingFile)
		editor.setNameFilter("Images (*.png *.jpg)")
		return editor
		
	def setModelData(self,editor, model,index):
  		fileNames = editor.selectedFiles()
		if len(fileNames) >=1 :
			model.setData(index,fileNames[0])
			return True
		else:
			return False
		
class MyDialog(QDialog):
	def __init__(self,parent=None):
		super(MyDialog,self).__init__(parent)
		
		self.tableWidget = QTableWidget(self)
		self.tableWidget.setColumnCount(1)
		self.tableWidget.setRowCount(2)
		
		__qtablewidgetitem1 = QTableWidgetItem()
		self.tableWidget.setItem(0, 0, __qtablewidgetitem1)
		__qtablewidgetitem2 = QTableWidgetItem()
		self.tableWidget.setItem(0, 1, __qtablewidgetitem2)
		self.tableWidget.setGeometry(QRect(10, 10, 300, 200))
		view = self.tableWidget
		delegate = MyStyledItemDelegate(view)
		view.setItemDelegate(delegate)
		self.resize(320, 230)
		
w = MyDialog()
w.show()

実行すると空の2項目を持った「QTableWidget」が入ったダイアログが表示される。ここでテーブルのセル1つをダブルクリックするとファイルダイアログが表示され、拡張子「png」、「jpg」のファイルがあればリストアップされる。適当なファイルを選択して「open」ボタンを押すと、ダブルクリックしたセルにそのファイル名が表示される。

これがファイル名を割り当ててみたところ。

fig 1

続きはまた次回。



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG

2022年06月14日

そろそろ頃合いなので

3dsmaxのアップグレードをやめてだいぶ経ってかなりバージョンも離れたのでここでmaxについての定期的な書き込みは終わりにします。



take_z_ultima at 11:30|この記事のURLComments(2)その他 | CG

2022年06月13日

Pyside2を使ったカスタムUI modo15 その33

今回はデリゲートの仕組みを使って「QTableWidget」の値の編集に「QSpinBox」を割り当ててみた。表の値の編集はセルをダブルクリックすると実行されてデリゲートの「createEditor()」メソッドの戻り値で引き渡すことが出来る。このエディタとテーブルが持っているデータとの相互変換なんかもデリゲートで割り当てが可能でシグナルとスロットの仕組みで実行されるようなんだけど今回はなにもしなくてもうまくやり取りが出来た。

import lx
import lxu
from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *

class MyStyledItemDelegate(QStyledItemDelegate):
	
	def __init__(self, parent=None):
		super(MyStyledItemDelegate, self).__init__(parent)
		
	def createEditor(self,parent,option,index):
		editor = QSpinBox(parent)
		editor.setFrame(False)
		editor.setMinimum(0)
		editor.setMaximum(100)
		return editor
		
class MyDialog(QDialog):
	def __init__(self,parent=None):
		super(MyDialog,self).__init__(parent)
		
		self.tableWidget = QTableWidget(self)
		self.tableWidget.setColumnCount(1)
		self.tableWidget.setRowCount(2)
		
		__qtablewidgetitem1 = QTableWidgetItem()
		__qtablewidgetitem1.setText('0');
		self.tableWidget.setItem(0, 0, __qtablewidgetitem1)
		__qtablewidgetitem2 = QTableWidgetItem()
		__qtablewidgetitem2.setText('10');
		self.tableWidget.setItem(0, 1, __qtablewidgetitem2)
		self.tableWidget.setGeometry(QRect(10, 10, 300, 200))
		view = self.tableWidget
		delegate = MyStyledItemDelegate(view)
		view.setItemDelegate(delegate)
		self.resize(320, 230)
		
w = MyDialog()
w.show()

これが実行結果。セルをダブルクリックするとスピンボックスが出て来て値を編集出来るようになった。

fig 1

続きはまた次回。



take_z_ultima at 11:30|この記事のURLComments(0)modo | CG
Archives