используйте пользовательские QListWidgetItems в QListWidget

#python #maya #pyside2

#python #maya #pyside2

Вопрос:

Эй, я хочу использовать пользовательские QListWidgetItems в моем QListWidget, но я не могу заставить его отображаться вообще.

Я хочу, чтобы QListWidgetItem выглядел так:

пользовательский QListWidgetItem

Вот мой код:

 from PySide2 import QtWidgets, QtCore, QtGui
from PySide2.QtCore import QSize
from PySide2.QtGui import QKeySequence, QFont, QPixmap, QWindow
from PySide2.QtWidgets import QShortcut, QLabel
from maya import OpenMayaUI
import maya.cmds as cmds
import sys

try:
    from shiboken import wrapInstance
    import shiboken
except:
    from shiboken2 import wrapInstance
    import shiboken2 as shiboken

allInfo = [{'label' : 'Giraffe',
            'command': 'print "The giraffe runs through the desert"',
            'annotation' : 'This command tells you what the giraffe is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Dragon',
            'command': 'print "The dragon flies towards the divine sky."',
            'annotation' : 'This command tells you what the dragon is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Dog',
            'command': 'print "The dog barks at the neighbor."',
            'annotation' : 'This command tells you what the dog is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Cat',
            'command': 'print "The cat does give a damn."',
            'annotation' : 'This command tells you what the cat is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Bull',
            'command': 'print "The bull runs towards the bullfighter"',
            'annotation' : 'This command tells you what the bull is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Ferret',
            'command': 'print "The ferret plays with the master."',
            'annotation' : 'This command tells you what the ferret is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Monkey',
            'command': 'print "The monkey is looking for bananas."',
            'annotation' : 'This command tells you what the monkey is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Bear',
            'command': 'print "The bear is looking for salmons."',
            'annotation' : 'This command tells you what the bear is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Ferret',
            'command': 'print "The ferret plays with the master."',
            'annotation' : 'This command tells you what the ferret is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Tiger',
            'command': 'print "The tiger tries to look like a cute cat.."',
            'annotation' : 'This command tells you what the tiger is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Lama',
            'command': 'print "The lama is spitting in your face."',
            'annotation' : 'This command tells you what the lama is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Lion',
            'command': 'print "The lion is looking for its prey."',
            'annotation' : 'This command tells you what the lion is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Fish',
            'command': 'print "The fish say blub."',
            'annotation' : 'This command tells you what the fish is doing.',
            'image': '',
            'menu': ''},

            {'label' : 'Panda',
            'command': 'print "The panda eats some bamboo."',
            'annotation' : 'This command tells you what the bamboo is doing.',
            'image': '',
            'menu': ''}]


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent = None):
        window = OpenMayaUI.MQtUtil.mainWindow()
        mayaWindow = shiboken.wrapInstance(long(window), QtWidgets.QMainWindow)
        super(MainWindow, self).__init__(mayaWindow)

        self.setWindowTitle('Test Window')
        self.resize(630, 400)
        self._window = None

        # main widget
        mainWidget = QtWidgets.QWidget(self)
        self.setCentralWidget(mainWidget)

        # layout initialize
        self.mainLayout = QtWidgets.QVBoxLayout()
        self.HBoxLayout = QtWidgets.QHBoxLayout()
        self.VBoxLayout = QtWidgets.QVBoxLayout()
        self.mainLayout.addLayout(self.VBoxLayout)
        self.VBoxLayout.addLayout(self.HBoxLayout)
        mainWidget.setLayout(self.mainLayout)

        # Add Widgets
        self.textField = QtWidgets.QLineEdit()
        self.textField.textChanged.connect(self.onTextChanged)

        self.listView = QtWidgets.QListWidget()
        self.listView.setMouseTracking(True)
        self.listView.itemDoubleClicked.connect(self.runCommand)

        self.HBoxLayout.addWidget(self.textField)
        self.VBoxLayout.addWidget(self.listView)
        self.textField.setFocus()

    def onTextChanged(self):
        self.searchForCommands()

    def runCommand(self):
        index = self.listView.currentRow()
        input = self.textField.text()
        if input == '' or input.isspace() or input == ' ' or input == None:
            item = None
        else:
            try:
                item = self.listView.item(index).text()
            except(AttributeError):
                item = None
        if item != None:
            if allInfo != None:
                ExecuteCommand(item, input)

    def showWindow(self):
        self.closeWindow()
        if self._window is None:
            self._window = MainWindow()
            self._window.show()

    def closeWindow(self):
        self.close()

    def searchForCommands(self):        
        maxListLength = 20
        input = self.textField.text().lower()
        if input == '' or input.isspace() or input == ' ' or input == None:
            if self.listView.count() > 0:
                self.listView.clear()
        else:
            if self.listView.count() > 0:
                self.listView.clear()
            i = 0
            for x in range(len(allInfo)):
                if i < maxListLength:
                    label = allInfo[x].get('label')
                    if input in label.lower():
                        item = QtWidgets.QListWidgetItem(label)
                        #item = ListWidgetItem()
                        #item.SetIcon('')
                        #item.SetMenu('test menu')
                        #item.SetName(label)
                        #item.SetAnnotation('Test annotation.')
                        self.listView.addItem(item)
                        i  = 1
                        continue
                    else:
                        pass
            self.listView.setCurrentRow(0)


class ListWidgetItem(QtWidgets.QListWidgetItem):
    def __init__(self):
        super(ListWidgetItem, self).__init__()
        self.mainHBoxLayout = QtWidgets.QHBoxLayout()
        self.iconLabel = QtWidgets.QLabel()
        self.mainHBoxLayout.addWidget(self.iconLabel)

        self.rightVBoxLayout = QtWidgets.QVBoxLayout()
        self.menuNameHBoxLayout = QtWidgets.QHBoxLayout()
        self.rightVBoxLayout.addLayout(self.menuNameHBoxLayout)

        self.nameLabel = QtWidgets.QLabel()
        self.annotationLabel = QtWidgets.QLabel()
        self.menuLabel = QtWidgets.QLabel()
        self.menuNameHBoxLayout.addWidget(self.menuLabel)
        self.menuNameHBoxLayout.addWidget(self.nameLabel)
        self.rightVBoxLayout.addWidget(self.annotationLabel)

    def SetName(self, text):
        self.nameLabel.setText(text)

    def SetAnnotation(self, text):
        self.annotationLabel.setText(text)

    def SetIcon(self, iconPath = ''):
        self.iconLabel.setPixmap(QtGui.QPixmap(iconPath))

    def SetMenu(self, text):
        self.menuLabel.setText(text)


def startApp(*args):
    app = QtWidgets.QApplication.instance()
    if app is None:
        app = QtWidgets.QApplication(sys.argv)
    mainWindow = MainWindow()
    mainWindow.showWindow()

def ExecuteCommand(listViewSelection, input, *args):
    ranCommand = False
    for x in range(len(allInfo)):
        if not ranCommand:
            if listViewSelection != None:
                label = allInfo[x].get('label')
                command = allInfo[x].get('command')
                if label == listViewSelection:
                    RunCommand(command)
                    ranCommand = True
        else:
            break

def RunCommand(command):
    cmds.evalDeferred(command)

if __name__ == '__main__':
    if not cmds.about(batch = True):
        startApp()
  

Закомментированная часть в строке 190 в searchForCommand — это моя попытка добавить пользовательский класс QListWidgetItem, который я написал в скрипте, но он не работает.

Итак, как мне заставить его работать так, чтобы QListWidgetItems выглядел так, как на прикрепленном изображении? Скрипт отлично работает в Maya2020, просто запустите его в редакторе сценариев, вам нужно дважды щелкнуть QListWidgetItem, чтобы запустить его команду. Класс ListWidgetItem — это моя попытка заставить его работать.

Ответ №1:

Возможно, вы можете рассмотреть возможность использования setItemWidget() наряду с обычными QListWidgetItem.

Например:

 ...

    def searchForCommands(self):        
        maxListLength = 20
        input = self.textField.text().lower()
        if input == '' or input.isspace() or input == ' ' or input == None:
            if self.listView.count() > 0:
                self.listView.clear()
        else:
            if self.listView.count() > 0:
                self.listView.clear()
            i = 0
            for x in range(len(allInfo)):
                if i < maxListLength:
                    label = allInfo[x].get('label')
                    if input in label.lower():
                        
                        itemWidget = ListWidgetItem()
                        itemWidget.SetIcon('')
                        itemWidget.SetMenu('test menu')
                        itemWidget.SetName(label)
                        itemWidget.SetAnnotation('Test annotation.')
  
                        item = QtWidgets.QListWidgetItem(label)
                        item.setSizeHint(itemWidget.sizeHint())
                        
                        self.listView.addItem(item)
                        self.listView.setItemWidget(item, itemWidget)
                        i  = 1
                        continue
                    else:
                        pass
            self.listView.setCurrentRow(0)


class ListWidgetItem(QtWidgets.QWidget):
    def __init__(self):
        super(ListWidgetItem, self).__init__()
                
        self.mainHBoxLayout = QtWidgets.QHBoxLayout()
        self.mainHBoxLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
        
        self.iconLabel = QtWidgets.QLabel(text="ICON")
        self.mainHBoxLayout.addWidget(self.iconLabel)
        
        self.rightVBoxLayout = QtWidgets.QVBoxLayout()
        self.rightVBoxLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
        self.mainHBoxLayout.addLayout(self.rightVBoxLayout)

        self.menuNameHBoxLayout = QtWidgets.QHBoxLayout()
        self.menuNameHBoxLayout.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)

        self.rightVBoxLayout.addLayout(self.menuNameHBoxLayout)
        self.nameLabel = QtWidgets.QLabel(text="Label")
        self.annotationLabel = QtWidgets.QLabel("Annotation")
        self.menuLabel = QtWidgets.QLabel("Menu")
        self.menuNameHBoxLayout.addWidget(self.menuLabel)
        self.menuNameHBoxLayout.addWidget(self.nameLabel)
        self.rightVBoxLayout.addWidget(self.annotationLabel)

        self.setLayout(self.mainHBoxLayout)

    def SetName(self, text):
        self.nameLabel.setText(text)

    def SetAnnotation(self, text):
        self.annotationLabel.setText(text)

    def SetIcon(self, iconPath = ''):
        self.iconLabel.setPixmap(QtGui.QPixmap(iconPath))

    def SetMenu(self, text):
        self.menuLabel.setText(text)


...
  

item.setSizeHint(itemWidget.sizeHint())
Здесь самая важная строка. Если вы не соответствуете размеру, он просто не будет работать.