Maya UI: QListWidget: items as QPushButtons?
-
Hi. I'm working on a UI in Maya to be able to drag and drop buttons. in a QListWidget.
I found an example online, but it was C++ so I've been trying to modify it for PySide2.
https://github.com/LazyanArtyom/qtdragdrop/blob/master/todolist.cppIt's pretty much what I want as is. Two lists where you can drag and drop(reorder) the items. Now I want them to be buttons that have a label, state and command attached.
I would be very grateful if someone could take a look. Most likely there's something that sticks out! :-)
from PySide2.QtWidgets import QApplication, QMainWindow, QWidget, QLabel, QVBoxLayout, QHBoxLayout, QListView, QToolBar, QAction from PySide2.QtGui import QIcon from PySide2.QtCore import Qt from functools import partial def maya_main_window(): main_window_ptr = omui.MQtUtil.mainWindow() return wrapInstance(int(main_window_ptr), QtWidgets.QWidget) class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=maya_main_window()): super(MainWindow, self).__init__(parent) self.num = 0 self.setWindowTitle("Button List Example") pWidget = QtWidgets.QWidget(self) pWidget.setStyleSheet("background-color: #ECF0F1") self.setCentralWidget(pWidget) pMainLayout = QtWidgets.QVBoxLayout() pWidget.setLayout(pMainLayout) pwTitle = QtWidgets.QLabel("To Do List", self) pMainLayout.addWidget(pwTitle) pwTitle.setAlignment(QtCore.Qt.AlignCenter) pwTitle.setStyleSheet("font-size: 30pt; margin: 10%;") pHLayoutLabels = QtWidgets.QHBoxLayout() pMainLayout.addLayout(pHLayoutLabels) plblPending = QtWidgets.QLabel("Pending", self) plblPending.setStyleSheet("font-size: 15pt;") pHLayoutLabels.addWidget(plblPending) plblCompleted = QtWidgets.QLabel("Completed", self) plblCompleted.setStyleSheet("font-size: 15pt;") pHLayoutLabels.addWidget(plblCompleted) pHLayout = QtWidgets.QHBoxLayout() pMainLayout.addLayout(pHLayout) self.m_pwPending = QtWidgets.QListWidget(self) self.m_pwPending.setDragEnabled(True) self.m_pwPending.setAcceptDrops(True) self.m_pwPending.setDropIndicatorShown(True) self.m_pwPending.setDefaultDropAction(QtCore.Qt.MoveAction) pHLayout.addWidget(self.m_pwPending) self.m_pwCompleted = QtWidgets.QListWidget(self) self.m_pwCompleted.setDragEnabled(True) self.m_pwCompleted.setAcceptDrops(True) self.m_pwCompleted.setDropIndicatorShown(True) self.m_pwCompleted.setDefaultDropAction(QtCore.Qt.MoveAction) pHLayout.addWidget(self.m_pwCompleted) self.addBtn = QtWidgets.QPushButton(self, 'add') self.addBtn.setText('ADD') self.addBtn.clicked.connect(self.addItem) pMainLayout.addWidget(self.addBtn) self.m_pwPending.setStyleSheet( "QListView { font-size: 10pt; font-weight: bold; }" "QListView::item { background-color: #E74C3C; padding: 10%;" "border: 1px solid #C0392B; }" "QListView::item::hover { background-color: #C0392B }") self.m_pwCompleted.setStyleSheet( "QListView { font-size: 10pt; font-weight: bold; }" "QListView::item { background-color: #2ECC71; padding: 10%;" "border: 1px solid #27AE60; }" "QListView::item::hover { background-color: #27AE60 }") def addItem(self, str): item = QtWidgets.QListWidgetItem(self.m_pwPending) button = QtWidgets.QPushButton() #button.setText(self.num) button.clicked.connect(print('1')) self.m_pwPending.setItemWidget(item, button) self.num +=1 if __name__ == "__main__": try: test_dialog.close() test_dialog.deleteLater() except: pass test_dialog = MainWindow() test_dialog.show() -
I haven't made any progess.
I've made a minor adjustment by creating my own pushbutton derived from QPushButton.
Basically I would like to replace the colored items with my PushButton. As it is now, I'm adding them to this widget because these widget seems reliable. They don't disappear when I drag them, but they also are not working as intended as when I drag them, my buttons get obscured/disappear. Well, I know too little of these things and this example is the closest I've found to what I'm looking for, but apparently I'm not doing it correctly.
from PySide2 import QtWidgets, QtGui, QtCore from functools import partial import maya.OpenMayaUI as omui from shiboken2 import wrapInstance from functools import partial def maya_main_window(): main_window_ptr = omui.MQtUtil.mainWindow() return wrapInstance(int(main_window_ptr), QtWidgets.QWidget) class myButton(QtWidgets.QPushButton): state = 0 def __init__(self): super().__init__() self.state = myButton.state self.setText(str(self.state)) self.setStyleSheet('QPushButton {background-color: #A3C1DA}') self.setStyleSheet('QPushButton {color: blue}') self.clicked.connect(self.onclick) self.setFixedHeight(30) myButton.state = myButton.state + 1 def onclick(self): print(self.state) class MainWindow(QtWidgets.QMainWindow): def __init__(self, parent=maya_main_window()): super(MainWindow, self).__init__(parent) self.num = 0 self.setWindowTitle("Button List Example") pWidget = QtWidgets.QWidget(self) pWidget.setStyleSheet("background-color: #ECF0F1") self.setCentralWidget(pWidget) pMainLayout = QtWidgets.QVBoxLayout() pWidget.setLayout(pMainLayout) pwTitle = QtWidgets.QLabel("To Do List", self) pMainLayout.addWidget(pwTitle) pwTitle.setAlignment(QtCore.Qt.AlignCenter) pwTitle.setStyleSheet("font-size: 30pt; margin: 10%;") pHLayoutLabels = QtWidgets.QHBoxLayout() pMainLayout.addLayout(pHLayoutLabels) plblPending = QtWidgets.QLabel("Pending", self) plblPending.setStyleSheet("font-size: 15pt;") pHLayoutLabels.addWidget(plblPending) plblCompleted = QtWidgets.QLabel("Completed", self) plblCompleted.setStyleSheet("font-size: 15pt;") pHLayoutLabels.addWidget(plblCompleted) pHLayout = QtWidgets.QHBoxLayout() pMainLayout.addLayout(pHLayout) self.m_pwPending = QtWidgets.QListWidget(self) self.m_pwPending.setDragEnabled(True) self.m_pwPending.setAcceptDrops(True) self.m_pwPending.setDropIndicatorShown(True) self.m_pwPending.setDefaultDropAction(QtCore.Qt.MoveAction) pHLayout.addWidget(self.m_pwPending) self.m_pwCompleted = QtWidgets.QListWidget(self) self.m_pwCompleted.setDragEnabled(True) self.m_pwCompleted.setAcceptDrops(True) self.m_pwCompleted.setDropIndicatorShown(True) self.m_pwCompleted.setDefaultDropAction(QtCore.Qt.MoveAction) pHLayout.addWidget(self.m_pwCompleted) self.addBtn = QtWidgets.QPushButton("ADD") self.addBtn.clicked.connect(self.addItem) pMainLayout.addWidget(self.addBtn) self.m_pwPending.setStyleSheet( "QListView { font-size: 10pt; font-weight: bold; }" "QListView::item { background-color: #E74C3C; padding: 10%;" "border: 1px solid #C0392B; }" "QListView::item::hover { background-color: #C0392B }" ) self.m_pwCompleted.setStyleSheet( "QListView { font-size: 10pt; font-weight: bold; }" "QListView::item { background-color: #2ECC71; padding: 10%;" "border: 1px solid #27AE60; }" "QListView::item::hover { background-color: #27AE60 }" ) def addItem(self): item = QtWidgets.QListWidgetItem(self.m_pwPending) # my custom button button = myButton() # or ''' button = QtWidgets.QPushButton() button.setFixedHeight(30) button.setText(str(self.num)) button.clicked.connect(self.print_this) ''' self.m_pwPending.setItemWidget(item, button) self.num +=1 def print_this(self): sender = self.sender() print(sender.text()) print('clicked') if __name__ == "__main__": try: test_dialog.close() test_dialog.deleteLater() except: pass test_dialog = MainWindow() test_dialog.show() -
Hi,
Using setItemWidget in this fashion goes against the recommendation.
You should take a look at QStyledItemDelegate. Use it to render the UI you would like. Doing so you will get back the drag and drop feature.
-
Hi,
Using setItemWidget in this fashion goes against the recommendation.
You should take a look at QStyledItemDelegate. Use it to render the UI you would like. Doing so you will get back the drag and drop feature.
-
@SGaist Thank you!
And just to be clear. What I'm after is a list of buttons that I can drag and drop to change their orders in the list. Nothing else really.
But this is still the preferred way to do it?