Mayaを使った制作現場で「資料画像をサッと確認したいな」と思う場面、多くないですか?
- チートシートを確認したい
- 三面図をパラパラ見たい
- 設定資料や参考画像をすぐ見たい
そんなとき、いちいち画像ビューアを立ち上げたり、ファイルを探したりするのは面倒……!
ということで今回は、PySide2で「フォルダ内の画像を←→キーで切り替えて表示できるビューア」を作ってみました。
🧩 できること
- 指定したフォルダ内の画像をすべて読み込み
- ← → キーで前後に切り替え
- Escキーで閉じる
- 画像は画面いっぱいに拡大表示(半透明)
- ミニランチャーからワンクリックで起動
用途は自由自在。チートシート、設定資料、三面図、絵コンテ、表情資料……全部これでOK!
🛠 使用技術
- Maya 2023
- PySide2(Maya標準搭載)
- Python 3.x(Maya同梱)
💻 実装のポイント
1. PySide2でGUI構築
MayaではPySide2を使って、QtベースのUIが組めます。
今回は QDialog
+ QLabel
を使って、画像を表示できるビューアを作成しました。
2. フォルダ内の画像を一括取得
os.listdir(folder)
でファイル一覧を取得し、拡張子が .jpg
, .png
, .bmp
などのものだけを抽出。
これで好きなだけ画像を放り込めます。
3. キー入力で切り替え
keyPressEvent()
をオーバーライドして、← → Esc キーに処理を割り当てています。
直感的に操作できます。
4. ミニランチャーで呼び出し
デザインも少しだけかわいく、ふわっとした水色UIに。
「画像ビューアを開く」ボタンからいつでもアクセスできます。
✨ こんなふうに使ってます
- キャラクターの三面図を切り替えて確認
- チートシートを手元で確認
🔚 おわりに
今後はアイデアを思いつき次第、改善していく予定です。
✅ コード全文はこちら
import os
from PySide2 import QtWidgets, QtGui, QtCore
import maya.OpenMayaUI as omui
from shiboken2 import wrapInstance
def get_maya_main_window():
ptr = omui.MQtUtil.mainWindow()
return wrapInstance(int(ptr), QtWidgets.QMainWindow)
class ImageViewer(QtWidgets.QDialog):
def __init__(self, folder_path, parent=get_maya_main_window()):
super(ImageViewer, self).__init__(parent)
self.setWindowTitle("画像ビューア")
self.setWindowFlags(QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint)
self.setWindowOpacity(0.9)
self.setWindowModality(QtCore.Qt.NonModal)
self.setFocusPolicy(QtCore.Qt.StrongFocus)
self.image_paths = self.load_images_from_folder(folder_path)
if not self.image_paths:
QtWidgets.QMessageBox.warning(self, "画像なし", "指定フォルダに画像がありません。")
self.close()
return
self.index = 0
self.screen = QtWidgets.QApplication.primaryScreen().geometry()
self.setGeometry(self.screen)
self.layout = QtWidgets.QVBoxLayout()
self.setLayout(self.layout)
self.label = QtWidgets.QLabel(self)
self.label.setAlignment(QtCore.Qt.AlignCenter)
self.layout.addWidget(self.label)
self.update_image()
close_btn = QtWidgets.QPushButton("閉じる", self)
close_btn.setFixedSize(100, 30)
close_btn.move(20, 20)
close_btn.clicked.connect(self.close)
close_btn.setStyleSheet("""
QPushButton {
background-color: #4dd0e1;
border: none;
border-radius: 10px;
padding: 6px 12px;
font-size: 13px;
color: white;
font-weight: bold;
}
QPushButton:hover {
background-color: #26c6da;
}
""")
def load_images_from_folder(self, folder):
exts = ['.jpg', '.jpeg', '.png', '.bmp', '.gif']
images = [os.path.join(folder, f) for f in sorted(os.listdir(folder))
if os.path.splitext(f)[1].lower() in exts]
return images
def update_image(self):
pixmap = QtGui.QPixmap(self.image_paths[self.index])
scaled = pixmap.scaled(self.screen.width(), self.screen.height(), QtCore.Qt.KeepAspectRatio)
self.label.setPixmap(scaled)
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Right:
self.index = (self.index + 1) % len(self.image_paths)
self.update_image()
elif event.key() == QtCore.Qt.Key_Left:
self.index = (self.index - 1) % len(self.image_paths)
self.update_image()
elif event.key() == QtCore.Qt.Key_Escape:
self.close()
class MiniLauncher(QtWidgets.QDialog):
def __init__(self, parent=get_maya_main_window()):
super(MiniLauncher, self).__init__(parent)
self.setWindowTitle("画像ビューア ランチャー")
self.setWindowFlags(QtCore.Qt.Tool | QtCore.Qt.WindowStaysOnTopHint)
self.setFixedSize(200, 100)
self.move(50, 200)
self.setStyleSheet("""
QDialog {
background-color: qlineargradient(
spread:pad, x1:0, y1:0, x2:1, y2:1,
stop:0 #d6f2fb, stop:1 #b3e5fc);
border: 2px solid #a2d4ec;
border-radius: 15px;
}
QPushButton {
background-color: #4dd0e1;
border: none;
border-radius: 12px;
padding: 8px 14px;
font-size: 14px;
color: white;
font-weight: bold;
}
QPushButton:hover {
background-color: #26c6da;
}
""")
btn = QtWidgets.QPushButton("画像ビューアを開く", self)
btn.clicked.connect(self.open_viewer)
layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(10, 10, 10, 10)
layout.addWidget(btn)
def open_viewer(self):
folder_path = r"C:\\Users\\micoa\\OneDrive\\デスクトップ\\maya\\viewer_images"
self.viewer = ImageViewer(folder_path)
self.viewer.show()
try:
mini_launcher.close()
except:
pass
mini_launcher = MiniLauncher()
mini_launcher.show()
🙌 最後に
「こんなの欲しかった!」と思ってくれた方、ぜひ試してみてください。