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()
これが実行結果。このようにマウスカーソルをあわせたセルのファイルパスが表示される。
続きはまた次回。
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」を生成して縦横比を計算してその比率を壊さないようにセルに収まるようにスケーリングするようにしてみた。
これが実行結果。
続きはまた次回。
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」ボタンを押すと、ダブルクリックしたセルにそのファイル名が表示される。
これがファイル名を割り当ててみたところ。
続きはまた次回。
2022年06月14日
そろそろ頃合いなので
3dsmaxのアップグレードをやめてだいぶ経ってかなりバージョンも離れたのでここでmaxについての定期的な書き込みは終わりにします。
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()
これが実行結果。セルをダブルクリックするとスピンボックスが出て来て値を編集出来るようになった。
続きはまた次回。