python 任务5.一些统计数据?

index.py
""" Update index.py """
app.route('/api/v1/stats')
# Retrieve number of each object by type
# Use count() method from storage

python 任务4. API的状态

app.py
""" Create app.py inside folder v1 """
  from models import storage
  from api.v1.views import app_views
  
  app = instance of Flask
  
  # register blueprint app_views to app
  
  @app.teardown_appcontext
  # declare a method here to call storage.close()
  
  if __name__ == "__main__":
    # run app
    # host = env variable HBNB_API_HOST or 0.0.0.0 as default
    # port = env variable HBNB_API_PORT or 5000 as default
    # threaded=True
  
__init__.py
""" Create __init__.py inside views folder in v1 """
from flask import Blueprint
from api.v1.views.index import * // ignore PEP8 complaint
app_views = instance of Blueprint // url prefix /api/v1
index.py
""" Create index.py inside views folder in v1 """
from api.v1.views import app_views

@app.route('/status')
# object = app_views
# returns JSON "status": "OK"

python 任务3.改进存储

filestorage.py
""" Update FileStorage """
def get(self, cls, id):
    ''' parameters:
        cls = string representing class name (like "City" or "State")
        id = string representing object ID (uuid4 format in object instatiation)
        returns:
        object (found by its class name and id) or None
    '''

def count(self, cls=None):
    ''' parameters:
        cls = string representing class name and is optional
        returns:
        number of objects in storage that match given class name
        (if no class name given it returns all objects)
    '''
dbstorage.py
""" Update DBStorage """
def get(self, cls, id):
    ''' parameters:
        cls = string representing class name (like "City" or "State")
        id = string representing object ID (uuid4 format in object instatiation)
        returns:
        object (found by its class name and id) or None
    '''

def count(self, cls=None):
    ''' parameters:
        cls = string representing class name and is optional
        returns:
        number of objects in storage that match given class name
        (if no class name given it returns all objects)
    '''

python Модели - Добавлениепредкаизродителя

models
parent_model = ParentModel.objects.get(id=1)
child_model = ChildModel(parent_model_ptr=parent_model)
child_model.field_name = 'Hello'
child_model.save_base(raw=True)

python 美元参考样本

reference.py

# %%

from pxr import Usd, UsdGeom, Sdf, Gf

USD_PATH_ROOT = "I:/usd_test"
kitchenSetRoot = USD_PATH_ROOT + "/Kitchen_set/assets/"

stage = Usd.Stage.CreateInMemory()

# この場合はPrimになるし
refPrimA = stage.DefinePrim("/World/BookGrp/Book")
refPrimB = stage.DefinePrim("/World/BookGrp/BookB")

# 指定のPrimに対してReferenceを読み込み
refPrimA.GetReferences().AddReference(kitchenSetRoot + 'Book/Book.usd')
refPrimB.GetReferences().AddReference(kitchenSetRoot + 'Book/Book.usd')


# %%
# 読み込んだリファレンスモデルに対してTransformを実行
xfA = UsdGeom.Xform(refPrimA)
xfA.AddRotateXOp().Set(90)

xfB = UsdGeom.Xform(refPrimB)
xfB.AddRotateXOp().Set(90)
xfB.AddTranslateOp().Set((50, 0, 0))

# %%

# DefinePrimで作ったGeomがかならずXformとは限らないような場合は
# XfromCommonAPIを使ってPrim指定でTransformを実行する
UsdGeom.XformCommonAPI(refPrimB).SetRotate((90, 0, 0))
UsdGeom.XformCommonAPI(refPrimB).SetTranslate((50, 0, 0))

# %%

print(stage.GetLayerStack())

# %%
print(stage.GetRootLayer().ExportToString())

# %%
stage.GetRootLayer().Export(USD_PATH_ROOT + "/refTest.usda")

python 美元参考测试

reference.py

# %%

from pxr import Usd, UsdGeom, Sdf, Gf

USD_PATH_ROOT = "I:/usd_test"
kitchenSetRoot = USD_PATH_ROOT + "/Kitchen_set/assets/"

stage = Usd.Stage.CreateInMemory()

# この場合はPrimになるし
refPrimA = stage.DefinePrim("/World/BookGrp/Book")
refPrimB = stage.DefinePrim("/World/BookGrp/BookB")
# この場合はGeomになる

# 指定のPrimに対してReferenceを読み込み
refPrimA.GetReferences().AddReference(kitchenSetRoot + 'Book/Book_payload.usd')
refPrimB.GetReferences().AddReference(kitchenSetRoot + 'Book/Book_payload.usd')


# %%
# 読み込んだリファレンスモデルに対してTransformを実行

xfA = UsdGeom.Xform(refPrimA)
xfA.AddRotateXOp().Set(90)

xfB = UsdGeom.Xform(refPrimB)
xfB.AddRotateXOp().Set(90)
xfB.AddTranslateOp().Set((50, 0, 0))


# %%
print(stage.GetRootLayer().ExportToString())

# %%
stage.GetRootLayer().Export(USD_PATH_ROOT + "/refTest.usda")

python 研究3美元目

anim_comp_meta.py
# -*- coding: utf-8 -*-
"""
USD学習3日目。

アニメーションさせたり、VariantSetをつくってみた

VariantSetを使用した場合、内部的にLayerが複数作られているので
そのままExportしてもSessionLayer(LayerStackに複数Layerがある状態)にVariantSetが入ってないので
データに反映されてなくてハマった。
(VariantSetもコンポジションアークの1つだから、コンポジション処理になる。なので、usdViewではPrimの色がオレンジ=Compになっていた)

usdファイルを分けていなくても、編集過程で複数のLayerStackができてたりするのが
いまいちよくわかっていない。

Layer = 1 usdファイル
Stage = Layerをコンポした結果

MetaDataもよくわからない
"""

# %%
import os.path
import os
from pxr import Usd, UsdGeom, Sdf, Gf, UsdUtils

Root  = "I:/usd_test"

# %%

sampleFile = Root + "/sample_USD.usda"

newScn = Usd.Stage.CreateInMemory()

# アニメーション ---------- #
newScn.SetStartTimeCode(0)
newScn.SetEndTimeCode(100)

# Mem上に作成したUSDファイルを色々コントロール
worldGeom = UsdGeom.Xform.Define(newScn, "/World")
cubeGeom = UsdGeom.Cube.Define(newScn, "/World/Cube")

# PrimのPath(sdfPath)の作成。
worldPath = Sdf.Path("/World")
helloPath = worldPath.AppendChild("hello")

# Cubeをアニメーション
spin = cubeGeom.AddRotateZOp(opSuffix='spin')
spin.Set(time=0, value=0)
spin.Set(time=100, value=360)

# VariantSet作成 https://graphics.pixar.com/usd/docs/Authoring-Variants.html
cubePrim = newScn.GetPrimAtPath(cubeGeom.GetPath())

# %%
vset = cubePrim.GetVariantSets().AddVariantSet('hogehoge')
vset.AddVariant('red')
vset.AddVariant('blue')
vset.AddVariant('green')
# 現在の選択VariantSetを変更
# GetVariantEditContextで、現在選択中のVariantに対して切り替え後(合成後)の値をSetすることで
# Switchできるようにできる。
colorAttr = UsdGeom.Gprim.Get(newScn, '/World/Cube').GetDisplayColorAttr()

vset.SetVariantSelection('red')
with vset.GetVariantEditContext():
    colorAttr.Set([(1, 0, 0)])
    
vset.SetVariantSelection('blue')
with vset.GetVariantEditContext():
    colorAttr.Set([(0, 0, 1)])

vset.SetVariantSelection('green')
with vset.GetVariantEditContext():
    colorAttr.Set([(0, 1, 0)])

# MetaDataについて
# Strongly Typed (強く定型化されている)
# Extensible (増築できる)
# unvarying(不変)
# Core metadata resolution rules vary(コアメタデータルールは様々である)
newScn.SetMetadata('comment', 'Hello World')

# %%
# Stage上でいろいろコンポジションアークの操作をしていると
# 中がどうなってるのかよくわからなくなる。
# (GetRootLayer、SessinLayer?)

# レイヤースタック確認
for i in newScn.GetLayerStack():
    print(i)
# %%
# 色々レイヤー取得テスト
print(newScn.GetUsedLayers())
# %%
# 現在のレイヤー?
print(newScn.GetSessionLayer())
# Rootのレイヤー?
print(newScn.GetRootLayer())
# %%
print(newScn.GetUsedLayers())
# %%
# 出力するときはRootでExport
newScn.GetRootLayer().Export(sampleFile)
# %%
print(newScn.GetRootLayer().ExportToString())
# %%
# Flattenすると、VariantSetではなく現在選択されているContextでFlattenになる
print(newScn.Flatten().ExportToString())

python simple_convnet_updated.py

simple_convnet_updated.py
'''Trains a simple convnet on the MNIST dataset.

Gets to 99.25% test accuracy after 12 epochs
(there is still a lot of margin for parameter tuning).
16 seconds per epoch on a GRID K520 GPU.
'''

from __future__ import print_function
import keras
from keras.datasets import mnist
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten
from keras.layers import Convolution2D as Conv2D, MaxPooling2D
from keras import backend as K
from keras.utils import np_utils

batch_size = 128
num_classes = 10
epochs = 12

# input image dimensions
img_rows, img_cols = 28, 28

# the data, shuffled and split between train and test sets
(x_train, y_train), (x_test, y_test) = mnist.load_data()

x_train = x_train.reshape(x_train.shape[0], img_rows, img_cols, 1)
x_test = x_test.reshape(x_test.shape[0], img_rows, img_cols, 1)
input_shape = (img_rows, img_cols, 1)

x_train = x_train.astype('float32')
x_test = x_test.astype('float32')
x_train /= 255
x_test /= 255
print('x_train shape:', x_train.shape)
print(x_train.shape[0], 'train samples')
print(x_test.shape[0], 'test samples')

# convert class vectors to binary class matrices
y_train = np_utils.to_categorical(y_train, num_classes)
y_test = np_utils.to_categorical(y_test, num_classes)

model = Sequential()
model.add(Conv2D(32, 3, 3,
                 activation='relu',
                 input_shape=input_shape))
model.add(Conv2D(64, 3, 3, activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
# model.add(Dropout(0.25))
model.add(Flatten())
model.add(Dense(128, activation='relu'))
# model.add(Dropout(0.5))
model.add(Dense(num_classes, activation='softmax'))

model.compile(loss=keras.metrics.categorical_crossentropy,
              optimizer=keras.optimizers.Adadelta(),
              metrics=['accuracy'])

model.fit(x_train, y_train,
          verbose=1,
          validation_data=(x_test, y_test))
score = model.evaluate(x_test, y_test, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

python tableView paintSample

tableView_painterSample.py
#!python3
# -*- coding: utf-8 -*-

import sys
import os.path

from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtUiTools import QUiLoader
from enum import IntEnum, auto


class Status(IntEnum):

    WAITING = auto()
    RUN = auto()
    FINISH = auto()
    ERROR = auto()


class StatusItem:

    def __init__(self, name, color):

        self.name = name
        self.color = color


CURRENT_PATH = os.path.dirname(os.path.abspath(sys.argv[0]))

# CHECKBOX Image ---- #
CHECK_IMG = CURRENT_PATH + "/icons/appbar.checkmark.thick.svg"
UNCHECK_IMG = CURRENT_PATH + "/icons/appbar.checkmark.thick.unchecked.svg"

# Painter COLOR ----- #
BACKGROUND_BASE_COLOR_A = QtGui.QColor(255, 255, 255)
BACKGROUND_BASE_COLOR_B = QtGui.QColor(240, 240, 240)
STATUS_FONT_COLOR = QtGui.QColor(255, 255, 255)

BACKGROUND_SELECTED = QtGui.QColor(204, 230, 255)
BACKGROUND_FOCUS = QtGui.QColor(240, 248, 255)

FONT_BASE_COLOR = QtGui.QColor(0, 0, 0)


STATUS_BG_COLOR = {
    Status.WAITING: StatusItem("待機中", QtGui.QColor(0, 0, 205)),
    Status.RUN: StatusItem("実行中", QtGui.QColor(148, 0, 211)),
    Status.FINISH: StatusItem("完了", QtGui.QColor(46, 139, 87)),
    Status.ERROR: StatusItem("エラー", QtGui.QColor(255, 0, 0))
}


# 列ごとに表示するItem
class DataItem(object):

    def __init__(self, name="",
                 check=False,
                 progress=0,
                 status=Status.WAITING,
                 comment=""):

        self.name = name
        self.check = check
        self.progess = progress
        self.status = status
        self.comment = comment

    def data(self, column):
        if column == 0:
            return self.name
        elif column == 1:
            return self.check
        elif column == 2:
            return self.progess
        elif column == 3:
            return STATUS_BG_COLOR[self.status]
        elif column == 4:
            return self.comment

    def setData(self, column, value):

        if column == 0:
            self.name = value
        elif column == 1:
            self.check = value
        elif column == 2:
            self.progess = value
        elif column == 3:
            self.status = value
        elif column == 4:
            self.comment = value


class TableDelegate(QtWidgets.QItemDelegate):

    def __init__(self, parent=None):
        super(TableDelegate, self).__init__(parent)

    def editorEvent(self, event, model, option, index):

        if index.column() == 1:
            if self.getCheckBoxRect(option).contains(event.pos().x(), event.pos().y()):
                if event.type() == QtCore.QEvent.MouseButtonPress:
                    currentValue = model.items[index.row()].data(index.column())
                    model.setData(index, not currentValue)
                    return True
        return False

    def createEditor(self, parent, option, index):
        """
        編集したいCellに対して、編集用のWidgetsを作成する
        """
        if index.column() == 0:
            return QtWidgets.QLineEdit(parent)

        if index.column() == 2:
            spin = QtWidgets.QSpinBox(parent)
            spin.setMinimum(0)
            spin.setMaximum(100)
            return spin

        if index.column() == 4:
            return QtWidgets.QTextEdit(parent)

    def setEditorData(self, editor, index):

        if index.column() == 0:
            value = index.model().data(index)
            editor.setText(value)

        if index.column() == 2:
            value = index.model().data(index, QtCore.Qt.DisplayRole)
            editor.setValue(value)

        if index.column() == 4:
            value = index.model().data(index)
            editor.setText(value)

    def setModelData(self, editor, model, index):

        value = None
        if index.column() == 0:
            value = editor.text()

        if index.column() == 2:
            value = editor.value()

        if index.column() == 4:
            value = editor.toPlainText()

        if value is not None:
            model.setData(index, value)

    def paint(self, painter, option, index):

        # 背景色を指定する
        data = index.data()

        bgColor = BACKGROUND_BASE_COLOR_A
        if (index.row() % 2) != 0:
            bgColor = BACKGROUND_BASE_COLOR_B

        if option.state & QtWidgets.QStyle.State_Selected:
            bgColor = BACKGROUND_SELECTED
        if option.state & QtWidgets.QStyle.State_HasFocus:
            bgColor = BACKGROUND_FOCUS

        brush = QtGui.QBrush(bgColor)
        painter.fillRect(option.rect, brush)

        if index.column() in [0, 4]:
            painter.setFont(QtGui.QFont("メイリオ", 9))
            painter.setPen(FONT_BASE_COLOR)
            painter.drawText(option.rect, QtCore.Qt.AlignCenter | QtCore.Qt.TextWordWrap, index.data())
            
        # 各列ごとの表示物を描画する
        if index.column() == 1:
            if data:
                pix = QtGui.QPixmap(CHECK_IMG)
            else:
                pix = QtGui.QPixmap(UNCHECK_IMG)

            rect = self.getCheckBoxRect(option)
            painter.drawPixmap(rect, pix)

        if index.column() == 2:
            bar = QtWidgets.QStyleOptionProgressBar()
            bar.rect = option.rect
            bar.rect.setHeight(option.rect.height() - 1)
            bar.rect.setTop(option.rect.top() + 1)
            bar.minimum = 0
            bar.maximum = 100
            bar.progress = int(data)
            bar.textVisible = True
            bar.text = str(data) + '%'
            bar.textAlignment = QtCore.Qt.AlignCenter
            QtWidgets.QApplication.style().drawControl(QtWidgets.QStyle.CE_ProgressBar, bar, painter)

        # Status表示
        if index.column() == 3:
            statusSizeX = 60
            statusSizeY = 20
            brush = QtGui.QBrush(data.color)
            painter.setPen(QtCore.Qt.NoPen)
            rect = QtCore.QRect(option.rect.left() + (option.rect.width() / 2) - (statusSizeX / 2),
                                option.rect.top() + (option.rect.height() / 2) - (statusSizeY / 2),
                                statusSizeX,
                                statusSizeY)
            painter.setBrush(brush)
            painter.drawRoundRect(rect)
            painter.setPen(STATUS_FONT_COLOR)
            painter.setFont(QtGui.QFont("メイリオ", 9))
            painter.drawText(rect, QtCore.Qt.AlignCenter | QtCore.Qt.TextWordWrap, data.name)

    def getCheckBoxRect(self, option, imgSize=30):

        return QtCore.QRect(option.rect.left() + (option.rect.width() / 2) - (imgSize / 2),
                            option.rect.top() + (option.rect.height() / 2) - (imgSize / 2),
                            imgSize,
                            imgSize)

    def sizeHint(self, option, index):

        if index.column() == 1:
            return self.getCheckBoxRect(option).size()

        if index.column() == 2:
            return QtCore.QSize(200, 30)

        if index.column() == 3:
            return QtCore.QSize(90, 30)

        if index.column() == 4:
            document = QtGui.QTextDocument(index.data())
            document.setDefaultFont(option.font)
            return QtCore.QSize(document.idealWidth() + 50, 15 * (document.lineCount() + 1))

        return super(TableDelegate, self).sizeHint(option, index)


class TableModel(QtCore.QAbstractTableModel):

    def __init__(self, parent=None):
        super(TableModel, self).__init__(parent)
        self.items = []

    def headerData(self, col, orientation, role):

        HEADER = ['名前', 'チェック', '進行状況', 'ステータス', '備考']

        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return HEADER[col]

        if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
            return str(col + 1).zfill(3)

    def addItem(self, item):

        self.items.append(item)
        self.layoutChanged.emit()

    def rowCount(self, parent=QtCore.QModelIndex()):
        u"""行数を返す"""
        return len(self.items)

    def columnCount(self, parent):
        u"""カラム数を返す"""
        return 5

    def setData(self, index, value, role=QtCore.Qt.EditRole):

        if role == QtCore.Qt.EditRole:
            index.data(QtCore.Qt.UserRole).setData(index.column(), value)
            self.headerDataChanged.emit(QtCore.Qt.Vertical, index.row(), index.row())
            self.dataChanged.emit(index, index)

    def data(self, index, role=QtCore.Qt.DisplayRole):

        if not index.isValid():
            return None

        if role == QtCore.Qt.DisplayRole:
            return self.items[index.row()].data(index.column())

        if role == QtCore.Qt.UserRole:
            return self.items[index.row()]

    def flags(self, index):
        return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled


class UISample(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(UISample, self).__init__(parent)

        self.tableView = QtWidgets.QTableView()
        self.setCentralWidget(self.tableView)

        self.model = TableModel()
        self.tableView.setModel(self.model)
        self.delegate = TableDelegate()
        self.tableView.setItemDelegate(self.delegate)

        # CellのサイズをSizeHintの値で固定する
        self.tableView.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
        self.tableView.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
        
        # Tableに表示したいオブジェクトを登録
        dataA = DataItem('AAAA', False, 0, Status.WAITING, 'ほげほげほげほげほげほげ\nふがふがふが\nほむほむほむ')
        dataB = DataItem('BBBB', False, 0, Status.FINISH, 'てすとてすと')
        dataC = DataItem('CCCC', False, 0, Status.ERROR, 'はろーはろー')
        dataD = DataItem('DDDD', False, 0, Status.RUN, 'ーーーーーーー')
        self.model.addItem(dataA)
        self.model.addItem(dataB)
        self.model.addItem(dataC)
        self.model.addItem(dataD)

        self.resize(800, 400)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    a = UISample()
    a.show()
    sys.exit(app.exec_())

python tableView paintSample

tableView_painterSample.py
#!python3
# -*- coding: utf-8 -*-

import sys
import os.path

from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtUiTools import QUiLoader
from enum import IntEnum, auto


class Status(IntEnum):

    WAITING = auto()
    RUN = auto()
    FINISH = auto()
    ERROR = auto()


class StatusItem:

    def __init__(self, name, color):

        self.name = name
        self.color = color


CURRENT_PATH = os.path.dirname(os.path.abspath(sys.argv[0]))

# CHECKBOX Image ---- #
CHECK_IMG = CURRENT_PATH + "/icons/appbar.checkmark.thick.svg"
UNCHECK_IMG = CURRENT_PATH + "/icons/appbar.checkmark.thick.unchecked.svg"

# Painter COLOR ----- #
BACKGROUND_BASE_COLOR_A = QtGui.QColor(255, 255, 255)
BACKGROUND_BASE_COLOR_B = QtGui.QColor(240, 240, 240)
STATUS_FONT_COLOR = QtGui.QColor(255, 255, 255)

BACKGROUND_SELECTED = QtGui.QColor(204, 230, 255)
BACKGROUND_FOCUS = QtGui.QColor(240, 248, 255)

FONT_BASE_COLOR = QtGui.QColor(0, 0, 0)


STATUS_BG_COLOR = {
    Status.WAITING: StatusItem("待機中", QtGui.QColor(0, 0, 205)),
    Status.RUN: StatusItem("実行中", QtGui.QColor(148, 0, 211)),
    Status.FINISH: StatusItem("完了", QtGui.QColor(46, 139, 87)),
    Status.ERROR: StatusItem("エラー", QtGui.QColor(255, 0, 0))
}


# 列ごとに表示するItem
class DataItem(object):

    def __init__(self, name="",
                 check=False,
                 progress=0,
                 status=Status.WAITING,
                 comment=""):

        self.name = name
        self.check = check
        self.progess = progress
        self.status = status
        self.comment = comment

    def data(self, column):
        if column == 0:
            return self.name
        elif column == 1:
            return self.check
        elif column == 2:
            return self.progess
        elif column == 3:
            return STATUS_BG_COLOR[self.status]
        elif column == 4:
            return self.comment

    def setData(self, column, value):

        if column == 0:
            self.name = value
        elif column == 1:
            self.check = value
        elif column == 2:
            self.progess = value
        elif column == 3:
            self.status = value
        elif column == 4:
            self.comment = value


class TableDelegate(QtWidgets.QItemDelegate):

    def __init__(self, parent=None):
        super(TableDelegate, self).__init__(parent)

    def editorEvent(self, event, model, option, index):

        if index.column() == 1:
            if self.getCheckBoxRect(option).contains(event.pos().x(), event.pos().y()):
                if event.type() == QtCore.QEvent.MouseButtonPress:
                    currentValue = model.items[index.row()].data(index.column())
                    model.setData(index, not currentValue)
                    return True
        return False

    def createEditor(self, parent, option, index):
        """
        編集したいCellに対して、編集用のWidgetsを作成する
        """
        if index.column() == 0:
            return QtWidgets.QLineEdit(parent)

        if index.column() == 2:
            spin = QtWidgets.QSpinBox(parent)
            spin.setMinimum(0)
            spin.setMaximum(100)
            return spin

        if index.column() == 4:
            return QtWidgets.QTextEdit(parent)

    def setEditorData(self, editor, index):

        if index.column() == 0:
            value = index.model().data(index)
            editor.setText(value)

        if index.column() == 2:
            value = index.model().data(index, QtCore.Qt.DisplayRole)
            editor.setValue(value)

        if index.column() == 4:
            value = index.model().data(index)
            editor.setText(value)

    def setModelData(self, editor, model, index):

        value = None
        if index.column() == 0:
            value = editor.text()

        if index.column() == 2:
            value = editor.value()

        if index.column() == 4:
            value = editor.toPlainText()

        if value is not None:
            model.setData(index, value)

    def paint(self, painter, option, index):

        # 背景色を指定する
        data = index.data()

        bgColor = BACKGROUND_BASE_COLOR_A
        if (index.row() % 2) != 0:
            bgColor = BACKGROUND_BASE_COLOR_B

        if option.state & QtWidgets.QStyle.State_Selected:
            bgColor = BACKGROUND_SELECTED
        if option.state & QtWidgets.QStyle.State_HasFocus:
            bgColor = BACKGROUND_FOCUS

        brush = QtGui.QBrush(bgColor)
        painter.fillRect(option.rect, brush)

        if index.column() in [0, 4]:
            painter.setFont(QtGui.QFont("メイリオ", 9))
            painter.setPen(FONT_BASE_COLOR)
            painter.drawText(option.rect, QtCore.Qt.AlignCenter | QtCore.Qt.TextWordWrap, index.data())
            
        # 各列ごとの表示物を描画する
        if index.column() == 1:
            if data:
                pix = QtGui.QPixmap(CHECK_IMG)
            else:
                pix = QtGui.QPixmap(UNCHECK_IMG)

            rect = self.getCheckBoxRect(option)
            painter.drawPixmap(rect, pix)

        if index.column() == 2:
            bar = QtWidgets.QStyleOptionProgressBar()
            bar.rect = option.rect
            bar.rect.setHeight(option.rect.height() - 1)
            bar.rect.setTop(option.rect.top() + 1)
            bar.minimum = 0
            bar.maximum = 100
            bar.progress = int(data)
            bar.textVisible = True
            bar.text = str(data) + '%'
            bar.textAlignment = QtCore.Qt.AlignCenter
            QtWidgets.QApplication.style().drawControl(QtWidgets.QStyle.CE_ProgressBar, bar, painter)

        # Status表示
        if index.column() == 3:
            statusSizeX = 60
            statusSizeY = 20
            brush = QtGui.QBrush(data.color)
            painter.setPen(QtCore.Qt.NoPen)
            rect = QtCore.QRect(option.rect.left() + (option.rect.width() / 2) - (statusSizeX / 2),
                                option.rect.top() + (option.rect.height() / 2) - (statusSizeY / 2),
                                statusSizeX,
                                statusSizeY)
            painter.setBrush(brush)
            painter.drawRoundRect(rect)
            painter.setPen(STATUS_FONT_COLOR)
            painter.setFont(QtGui.QFont("メイリオ", 9))
            painter.drawText(rect, QtCore.Qt.AlignCenter | QtCore.Qt.TextWordWrap, data.name)

    def getCheckBoxRect(self, option, imgSize=30):

        return QtCore.QRect(option.rect.left() + (option.rect.width() / 2) - (imgSize / 2),
                            option.rect.top() + (option.rect.height() / 2) - (imgSize / 2),
                            imgSize,
                            imgSize)

    def sizeHint(self, option, index):

        if index.column() == 1:
            return self.getCheckBoxRect(option).size()

        if index.column() == 2:
            return QtCore.QSize(200, 30)

        if index.column() == 3:
            return QtCore.QSize(90, 30)

        if index.column() == 4:
            document = QtGui.QTextDocument(index.data())
            document.setDefaultFont(option.font)
            return QtCore.QSize(document.idealWidth() + 50, 15 * (document.lineCount() + 1))

        return super(TableDelegate, self).sizeHint(option, index)


class TableModel(QtCore.QAbstractTableModel):

    def __init__(self, parent=None):
        super(TableModel, self).__init__(parent)
        self.items = []

    def headerData(self, col, orientation, role):

        HEADER = ['名前', 'チェック', '進行状況', 'ステータス', '備考']

        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return HEADER[col]

        if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole:
            return str(col + 1).zfill(3)

    def addItem(self, item):

        self.items.append(item)
        self.layoutChanged.emit()

    def rowCount(self, parent=QtCore.QModelIndex()):
        u"""行数を返す"""
        return len(self.items)

    def columnCount(self, parent):
        u"""カラム数を返す"""
        return 5

    def setData(self, index, value, role=QtCore.Qt.EditRole):

        if role == QtCore.Qt.EditRole:
            index.data(QtCore.Qt.UserRole).setData(index.column(), value)
            self.headerDataChanged.emit(QtCore.Qt.Vertical, index.row(), index.row())
            self.dataChanged.emit(index, index)

    def data(self, index, role=QtCore.Qt.DisplayRole):

        if not index.isValid():
            return None

        if role == QtCore.Qt.DisplayRole:
            return self.items[index.row()].data(index.column())

        if role == QtCore.Qt.UserRole:
            return self.items[index.row()]

    def flags(self, index):
        return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled


class UISample(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(UISample, self).__init__(parent)

        self.tableView = QtWidgets.QTableView()
        self.setCentralWidget(self.tableView)

        self.model = TableModel()
        self.tableView.setModel(self.model)
        self.delegate = TableDelegate()
        self.tableView.setItemDelegate(self.delegate)

        # CellのサイズをSizeHintの値で固定する
        self.tableView.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
        self.tableView.verticalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
        
        # Tableに表示したいオブジェクトを登録
        dataA = DataItem('AAAA', False, 0, Status.WAITING, 'ほげほげほげほげほげほげ\nふがふがふが\nほむほむほむ')
        dataB = DataItem('BBBB', False, 0, Status.FINISH, 'てすとてすと')
        dataC = DataItem('CCCC', False, 0, Status.ERROR, 'はろーはろー')
        dataD = DataItem('DDDD', False, 0, Status.RUN, 'ーーーーーーー')
        self.model.addItem(dataA)
        self.model.addItem(dataB)
        self.model.addItem(dataC)
        self.model.addItem(dataD)

        self.resize(800, 400)


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    a = UISample()
    a.show()
    sys.exit(app.exec_())