pyside2 实现一个带有滑块视觉的输入框
pyside2 Implement an input box with a slider visual
我想在 Autodesk Maya 中使用 pyside2 实现类似搅拌机的 属性 调整框,如下所示。
我找到了一些类似的链接,但没有成功,具体怎么做。
How to create graphic slider in Python that can be modified with mouse?
import sys
from PySide2.QtCore import Qt, QEvent
from PySide2.QtGui import QStandardItemModel, QStandardItem
from PySide2.QtWidgets import QApplication, QWidget, QTableView, QHBoxLayout, QStyledItemDelegate, QStyle, QStyleOptionProgressBar, QStyleOptionButton
class MyTableView(QTableView):
def __init__(self):
super(MyTableView, self).__init__()
class MyDelgate(QStyledItemDelegate):
def __init__(self):
super(MyDelgate, self).__init__()
def paint(self, painter, option, index):
if index.column() == 1:
style = QStyleOptionProgressBar()
style.minimum = 0
style.maximum = 10
style.progress= index.data(Qt.DisplayRole)
style.rect = option.rect
QApplication.style().drawControl(QStyle.CE_ProgressBar, style, painter)
elif index.column() == 2:
style = QStyleOptionButton()
if index.data(Qt.DisplayRole) == True:
style.state = QStyle.State_On
else:
style.state = QStyle.State_Off
style.state |= QStyle.State_Enabled
style.rect = option.rect
style.rect.setX(option.rect.x() + option.rect.width() / 2 - 7)
QApplication.style().drawControl(QStyle.CE_CheckBox, style, painter)
else:
return QStyledItemDelegate.paint(self, painter, option, index)
def editorEvent(self, event, model, option, index):
if index.column() == 2:
if event.type() == QEvent.MouseButtonPress and option.rect.contains(event.pos()):
data = not index.data(Qt.DisplayRole)
model.setData(index, data, Qt.DisplayRole)
return True
else:
return QStyledItemDelegate.editorEvent(self, event, model, option, index)
class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
self.mode = QStandardItemModel()
root = self.mode.invisibleRootItem()
item1 = QStandardItem()
item1.setData('a', Qt.DisplayRole)
item2 = QStandardItem()
item2.setData(1, Qt.DisplayRole)
item3 = QStandardItem()
item3.setData(False, Qt.DisplayRole)
item4 = QStandardItem()
item4.setData('b', Qt.DisplayRole)
item5 = QStandardItem()
item5.setData(2, Qt.DisplayRole)
item6 = QStandardItem()
item6.setData(True, Qt.DisplayRole)
root.setChild(0, 0, item1)
root.setChild(0, 1, item2)
root.setChild(0, 2, item3)
root.setChild(1, 0, item4)
root.setChild(1, 1, item5)
root.setChild(1, 2, item6)
tableView = MyTableView()
tableView.setModel(self.mode)
tableView.setItemDelegate(MyDelgate())
layout = QHBoxLayout()
layout.addWidget(tableView)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
感谢任何建议。
您需要在editorEvent
中跟踪鼠标位置,并根据样式选项的子元素矩形计算比例。
def editorEvent(self, event, model, option, index):
if index.column() == 1:
if event.type() in (event.MouseMove, event.MouseButtonPress):
progressOpt = QStyleOptionProgressBar()
progressOpt.rect = option.rect
style = option.widget.style()
rect = style.subElementRect(style.SE_ProgressBarGroove,
progressOpt, option.widget)
pos = max(0, min(rect.width(), event.x() - rect.x()))
model.setData(index, round(pos / rect.width() * 10), Qt.DisplayRole)
return True
elif index.column() == 2:
if event.type() == QEvent.MouseButtonPress and option.rect.contains(event.pos()):
data = not index.data(Qt.DisplayRole)
model.setData(index, data, Qt.DisplayRole)
return True
return super().editorEvent(event, model, option, index)
我想在 Autodesk Maya 中使用 pyside2 实现类似搅拌机的 属性 调整框,如下所示。
我找到了一些类似的链接,但没有成功,具体怎么做。 How to create graphic slider in Python that can be modified with mouse?
import sys
from PySide2.QtCore import Qt, QEvent
from PySide2.QtGui import QStandardItemModel, QStandardItem
from PySide2.QtWidgets import QApplication, QWidget, QTableView, QHBoxLayout, QStyledItemDelegate, QStyle, QStyleOptionProgressBar, QStyleOptionButton
class MyTableView(QTableView):
def __init__(self):
super(MyTableView, self).__init__()
class MyDelgate(QStyledItemDelegate):
def __init__(self):
super(MyDelgate, self).__init__()
def paint(self, painter, option, index):
if index.column() == 1:
style = QStyleOptionProgressBar()
style.minimum = 0
style.maximum = 10
style.progress= index.data(Qt.DisplayRole)
style.rect = option.rect
QApplication.style().drawControl(QStyle.CE_ProgressBar, style, painter)
elif index.column() == 2:
style = QStyleOptionButton()
if index.data(Qt.DisplayRole) == True:
style.state = QStyle.State_On
else:
style.state = QStyle.State_Off
style.state |= QStyle.State_Enabled
style.rect = option.rect
style.rect.setX(option.rect.x() + option.rect.width() / 2 - 7)
QApplication.style().drawControl(QStyle.CE_CheckBox, style, painter)
else:
return QStyledItemDelegate.paint(self, painter, option, index)
def editorEvent(self, event, model, option, index):
if index.column() == 2:
if event.type() == QEvent.MouseButtonPress and option.rect.contains(event.pos()):
data = not index.data(Qt.DisplayRole)
model.setData(index, data, Qt.DisplayRole)
return True
else:
return QStyledItemDelegate.editorEvent(self, event, model, option, index)
class MyWidget(QWidget):
def __init__(self):
super(MyWidget, self).__init__()
self.mode = QStandardItemModel()
root = self.mode.invisibleRootItem()
item1 = QStandardItem()
item1.setData('a', Qt.DisplayRole)
item2 = QStandardItem()
item2.setData(1, Qt.DisplayRole)
item3 = QStandardItem()
item3.setData(False, Qt.DisplayRole)
item4 = QStandardItem()
item4.setData('b', Qt.DisplayRole)
item5 = QStandardItem()
item5.setData(2, Qt.DisplayRole)
item6 = QStandardItem()
item6.setData(True, Qt.DisplayRole)
root.setChild(0, 0, item1)
root.setChild(0, 1, item2)
root.setChild(0, 2, item3)
root.setChild(1, 0, item4)
root.setChild(1, 1, item5)
root.setChild(1, 2, item6)
tableView = MyTableView()
tableView.setModel(self.mode)
tableView.setItemDelegate(MyDelgate())
layout = QHBoxLayout()
layout.addWidget(tableView)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MyWidget()
w.resize(500, 300)
w.move(300, 300)
w.setWindowTitle('Simple')
w.show()
sys.exit(app.exec_())
感谢任何建议。
您需要在editorEvent
中跟踪鼠标位置,并根据样式选项的子元素矩形计算比例。
def editorEvent(self, event, model, option, index):
if index.column() == 1:
if event.type() in (event.MouseMove, event.MouseButtonPress):
progressOpt = QStyleOptionProgressBar()
progressOpt.rect = option.rect
style = option.widget.style()
rect = style.subElementRect(style.SE_ProgressBarGroove,
progressOpt, option.widget)
pos = max(0, min(rect.width(), event.x() - rect.x()))
model.setData(index, round(pos / rect.width() * 10), Qt.DisplayRole)
return True
elif index.column() == 2:
if event.type() == QEvent.MouseButtonPress and option.rect.contains(event.pos()):
data = not index.data(Qt.DisplayRole)
model.setData(index, data, Qt.DisplayRole)
return True
return super().editorEvent(event, model, option, index)