Search code examples
pythonmayapyside2

Maya PySide2 UI Get QLineEdit value


I am starting using QtCreator to create a UI for a little tool for Maya 2017. QtCreator gave me this .ui file:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>DockWidget</class>
 <widget class="QDockWidget" name="DockWidget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>550</width>
    <height>251</height>
   </rect>
  </property>
  <property name="floating">
   <bool>true</bool>
  </property>
  <property name="windowTitle">
   <string>Attr Editor</string>
  </property>
  <widget class="QWidget" name="dockWidgetContents">
   <widget class="QLineEdit" name="attr_value_textfield">
    <property name="geometry">
     <rect>
      <x>130</x>
      <y>128</y>
      <width>391</width>
      <height>20</height>
     </rect>
    </property>
    <property name="toolTip">
     <string>attr_value</string>
    </property>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>227</x>
      <y>20</y>
      <width>97</width>
      <height>25</height>
     </rect>
    </property>
    <property name="font">
     <font>
      <family>Century Gothic</family>
      <pointsize>16</pointsize>
      <weight>75</weight>
      <bold>true</bold>
     </font>
    </property>
    <property name="text">
     <string>Attr Editor</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton_2">
    <property name="geometry">
     <rect>
      <x>240</x>
      <y>180</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>Submit</string>
    </property>
    <property name="+command" stdset="0">
     <string>submitCommand</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_3">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>130</y>
      <width>80</width>
      <height>16</height>
     </rect>
    </property>
    <property name="font">
     <font>
      <family>Century Gothic</family>
     </font>
    </property>
    <property name="text">
     <string>Attribute Value</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="attr_name_textfield">
    <property name="geometry">
     <rect>
      <x>130</x>
      <y>78</y>
      <width>391</width>
      <height>20</height>
     </rect>
    </property>
    <property name="toolTip">
     <string>attr_name</string>
    </property>
    <property name="whatsThis">
     <string/>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton_3">
    <property name="geometry">
     <rect>
      <x>440</x>
      <y>180</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>Cancel</string>
    </property>
    <property name="+command" stdset="0">
     <string>cancelCommand</string>
    </property>
   </widget>
   <widget class="QPushButton" name="display_button">
    <property name="geometry">
     <rect>
      <x>30</x>
      <y>180</y>
      <width>75</width>
      <height>23</height>
     </rect>
    </property>
    <property name="text">
     <string>Display</string>
    </property>
    <property name="+command" stdset="0">
     <string>displayCommand</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>80</y>
      <width>82</width>
      <height>16</height>
     </rect>
    </property>
    <property name="font">
     <font>
      <family>Century Gothic</family>
     </font>
    </property>
    <property name="text">
     <string>Attribute Name</string>
    </property>
   </widget>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

And I have this code which displays my UI:

import maya.cmds as cmds 
from PySide2.QtWidgets import *
from PySide2.QtCore import *

if cmds.window(main_window, ex = True):
    cmds.deleteUI(main_window)

main_window = cmds.loadUI(uiFile = "C:/Users/thornydre/Desktop/attreditorui.ui")
cmds.showWindow(main_window)

def displayCommand(e):
    print(attr_name_textfield.text())
    print(attr_value_textfield.text())

def submitCommand(e):
    attr_name = attr_name_textfield.text()
    attr_value = attr_value_textfield.text()

    is_string = False
    
    try:
        new_attr_value = float(attr_value)
        if float(attr_value) % 1 == 0:
            new_attr_value = int(attr_value)
    except:
        is_string = True
        new_attr_value = attr_value

    print(new_attr_value)
        
    for name in cmds.ls(sl = True):
        if is_string:
            cmds.setAttr(name + "." + attr_name, new_attr_value, type = "string")
        else:
            cmds.setAttr(name + "." + attr_name, new_attr_value)

def cancelCommand(e):
    cmds.deleteUI(main_window, window = True)

And if I click on my display_button, I have an error:

# Result: dockWidgetContents|display_button #
# Error: AttributeError: file line 12: 'bool' object has no attribute 'attr_name_textfield' #

I tried to do it with a subclass of QtWidgets.QWidget as I found somewhere on the internet, but I don't really found any tutorial on how to build it properly:

from PySide2 import QtCore, QtGui, QtWidgets, QtUiTools

class Interface(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super(Interface, self).__init__(parent)
        ui_filename = "C:/Users/thornydre/Desktop/attreditorui.ui"
        ui_file = QtCore.QFile(ui_filename)
        ui_file.open(QtCore.QFile.ReadOnly)
        self.ui = QtUiTools.QUiLoader().load(ui_file, parentWidget=self)
        ui_file.close()
        
    def connectInterface(self):
        QtCore.QtObject.connect(self.displayCommand, QtCore.SIGNAL("clicked()"), self.displayCommandWin)
        
    def displayCommand(self):
        print(self.attr_name_textfield.text())
        print(self.attr_value_textfield.text())
        
def main():
    global ui
    ui = Interface()

if __name__ == "__main__":
    main()

Same thing here, the UI shows up, but really nothing happens with clicking on the display_button


Solution

  • Your second try with the class seems good but it's completely normal that you can't execute displayCommand, your button is not connected to your method.

    Juste delete your connectInterface method, and right after ui_file.close() copy this: self.ui.display_button.clicked.connect(self.displayCommand)

    It should work better :) (and you have to use the eyllanesc solution too to access to the widgets values)