I've been following This Tutorial on using a .UI file from QT designer in a Maya plugin. It states that, in order to query the value of a QtextEdit field after the UI has been loaded into Maya, I need to do the following:
So now when we load our QT Ui inside of maya we can query the text of
our line edit every time we want to by using the following line of
code:
pm.textField('textFieldName', query = True, text = True)
However I can't seem to get this to function. I'm loading the UI as follows:
# Load our window and put it into a variable.
ebWin = cmds.loadUI(uiFile = self.BE_UIpath)
No issues there, when I try cmds.showWindow(ebWin), everything works and looks exactly as intended. Now, when I try to query the QtextEdit I've named 'exportDirectoryTF', Maya insists it does not exist. I've tried two different approaches:
approach A:
# Connect Functions to the buttons.
exportDir = ebWin.textField('exportDirectoryTF', query = True, text = True)
which outputs:
# Error: 'unicode' object has no attribute 'textField'
# # Traceback (most recent call last):
# # File "C:/Users/Censored/Documents/maya/2018/plug-ins/EB_pi_cmds.py", line 39, in doIt
# # exportDir = ebWin.textField('exportDirectoryTF', query = True, text = True)
# # AttributeError: 'unicode' object has no attribute 'textField'
and approach B:
import maya.cmds as cmds
# Connect Functions to the buttons.
exportDir = cmds.textField('exportDirectoryTF', query = True, text = True)
which returns:
# RuntimeError: Object 'exportDirectoryTF' not found.
# # Traceback (most recent call last):
# # File "C:/Users/Censored/Documents/maya/2018/plug-ins/EB_pi_cmds.py", line 39, in doIt
# # exportDir = cmds.textField('exportDirectoryTF', query = True, text = True)
# # RuntimeError: Object 'exportDirectoryTF' not found. #
The tutorial has 'pm.textField('textFieldName', q = True, text = True)', and I can't figure out where the "pm" came from, if it is supposed to indicate the variable from loading the UI or the maya Python textField command, or neither.
If anyone could point me in the right direction here, it would be greatly appreciated.
From your code it is not visible at which time you try to execute the textField cmd. This code below works fine for me. The test.ui only contains a widget with a lineEdit field called "lineEdit". Querying the text field only works if the window is visible. If you close the window and try to query the text field, you get the "object not found" error.
ui = "D:/temp/test.ui"
qtW = cmds.loadUI(uiFile = ui)
cmds.showWindow(qtW)
cmds.textField("lineEdit", query=True, text=True)
Related
I've been trying to get attachment image data from documents in Cloudant.
I can successfully do it once a document is selected (direct extract with _id, etc).
Now trying to do it in combination with "query" operation using selector, I run into trouble.
Here is my code.
targetName="chibika33"
targetfile="chibitest.png"
#--------------------------------------------------
# get all the documents with the specific nameField
#--------------------------------------------------
myDatabase.create_query_index(fields = ['nameField'])
selector = {'nameField': {'$eq': targetName}}
docs = myDatabase.get_query_result(selector)
#--------------------------------------------------
# get the attachment files to them, save it locally
#--------------------------------------------------
count = 0
for doc in docs:
count=count+1
result_filename="result%03d.png"%(count)
dataContent = doc.get_attachment(targetfile, attachment_type='binary')
dataContentb =base64.b64decode(dataContent)
with open(result_filename,'wb') as output:
output.write(dataContentb)
Causes error as;
Traceback (most recent call last):
File "view8.py", line 44, in <module>
dataContent = doc.get_attachment(targetfile, attachment_type='binary')
AttributeError: 'dict' object has no attribute 'get_attachment'
So far, I've been unable to find any API for converting dict to document object in the python-cloudant-document...[python-cloudant document]: http://python-cloudant.readthedocs.io/en/latest/index.html
Any advise would be highly appreciated.
The returned structure from get_query_result(...) isn't an array of documents.
Try:
resp = myDatabase.get_query_result(selector)
for doc in resp['docs']:
# your code here
See the docs at:
http://python-cloudant.readthedocs.io/en/latest/database.html#cloudant.database.CloudantDatabase.get_query_result
I am trying to submit a form and retrieve some data
with dryscrape but when I execute the program, I get the error:
Traceback (most recent call last):
File "easyjettest.py", line 22, in <module>
originairport_field.set(originairport)
AttributeError: 'NoneType' object has no attribute 'set'
I really can't figure out what is the problem. I've read the documentation and searched as much as I could online.
The code is the following:
import dryscrape
import sys
if 'linux' in sys.platform:
# start xvfb in case no X is running. Make sure xvfb
# is installed, otherwise this won't work!
dryscrape.start_xvfb()
originairport = 'Cyprus (Larnaca) LCA'
destinationairport = 'London Gatwick LGW'
odate = '16/08/2016'
adate = '18/08/2016'
adults = '1'
sess = dryscrape.Session(base_url = 'http://www.easyjet.com/en/')
sess.set_attribute('auto_load_images', False)
sess.visit('/')
originairport_field = sess.at_xpath('.//*[#id="acOriginAirport"]')
originairport_field.set(originairport)
destinationairport_field = sess.at_xpath('.//* [#id="acDestinationAirport"]')
destinationairport_field.set(destinationairport)
odate_field = sess.at_xpath('.//*[#id="oDate"]')
odate_field.set(odate)
rdate_field = session.at_xpath('.//*[#id="rDate"]')
rdate_field.set(rdate)
adults_field = session.at_xpath('.//*[#id="numberOfAdults"]')
adults_field.set(adults)
originairport_field.form().submit()
# extract all links
for link in session.xpath('//a[#href]'):
print link['href']
Check in which line the error is taking place ,probably any of the variables originairport_field, destinationairport_field, odate_field ,rdate_field,adults_field is assigned none.
By the way from where does the session in the lines where you set the values of rdate_field and adults_field come from? isnt that sess
Edit:
From your updated error info probably sess.at_xpath('.//*[#id="acOriginAirport"]') isnt returning anything.
I had 2 questions in which I am not sure if this can by done in-scene using python.
My Maya version is not installed with any Mental Ray. There are times in which when I opened files (that was installed with Mental Ray), I keep getting errors such as:
// Warning: file: /apps/Linux64/aw/maya2014/scripts/others/supportRenderers.mel line 77: The renderer "mentalRay" used by this scene, is not currently available. The Maya Software renderer will be used instead. //
// Error: file: /apps/Linux64/aw/maya2014/scripts/others/supportRenderers.mel line 82: setAttr: The attribute 'defaultRenderGlobals.currentRenderer' is locked or connected and cannot be modified. //
// Error: file: /apps/Linux64/aw/maya2014/scripts/others/unifiedRenderGlobalsWindow.mel line 415: The renderer mentalRay is not registered yet. //
// Error: line 1: The renderer mentalRay is not registered yet. //
I tried using the following code to 'rectify' the issue:
list = cmds.listAttr("defaultRenderGlobals", l=True)
for item in list:
cmds.setAttr("defaultRenderGlobals." + item, l=False)
mel.eval('updateCurrentRendererSel("unifiedRenderGlobalsRendererSelOptionMenu");')
mel.eval('loadPreferredRenderGlobalsPreset("mayaHardware");')
but then I will get another bunch of error if I tried to open up my Render Settings
//Error: Object ‘tabForm’ not found.
And so, are there any ways in which this can be remedied in-scene
Attached is the screenshot:
Note: See the "Update" section below in this answer to find the full solution.
Why don't you just try unlocking and setting the currentRenderer value using setAttr itself.
cmds.setAttr("defaultRenderGlobals.currentRenderer", l=False)
cmds.setAttr("defaultRenderGlobals.currentRenderer", "mayaHardware", type="string")
You are getting the error //Error: Object ‘tabForm’ not found. because the render settings window failed to load, probably because of unregistered mentalRay. So AVOID calling the following until current renderer is changed:
mel.eval('updateCurrentRendererSel("unifiedRenderGlobalsRendererSelOptionMenu");')
mel.eval('loadPreferredRenderGlobalsPreset("mayaHardware");')
Update:
From the updates in the question and the comments below, we come to understand that the problem here is that Maya fails to construct the render settings window's UI properly when it encounters a missing renderer or render settings errors. This leads to parent UI components, like the tabs and frames to not being built. As a result, when the renderer is switched, the render settings UI tries to load the corresponding settings into these tabs but cannot find them and stops.
To work around this, we can just set the render settings we want, delete the render settings window's UI completely and reload it. I wrote a quick function for this. This will fix it.
import maya.cmds as cmds
import maya.mel as mel
def remake_render_settings_ui(renderer="mayaSoftware"):
""" Remakes the render settings window """
# Unlock the render globals' current renderer attribute
cmds.setAttr("defaultRenderGlobals.currentRenderer", l=False)
# Sets the current renderer to given renderer
cmds.setAttr("defaultRenderGlobals.currentRenderer", renderer, type="string")
# Deletes the render settings window UI completely
if cmds.window("unifiedRenderGlobalsWindow", exists=True):
cmds.deleteUI("unifiedRenderGlobalsWindow")
# Remake the render settings UI
mel.eval('unifiedRenderGlobalsWindow;')
if __name__ == "__main__":
remake_render_settings_ui(renderer="mayaHardware")
Caveat: This will not prevent the UI from getting lost again if the faulty renderer is somehow selected again. To prevent that, it is better to unload the renderer's plugin. In any case, if the above method is called again, the window should be fixed.
Hope this was useful.
There are a few problems that arises in the Render Settings while opening a scene file that contains traces of Mental Ray in a machine installed with no Mental Ray plugin
For some reasons, despite unlocking and setting a renderer in the defaultRenderGlobals in the scene, the render settings will continue to have problems as mentioned in the thread post or comments in kartikg3 answer.
I found a workaround which is -
Unlock the defaultRenderGlobals
Save the said file Delete any existing unifiedRenderGlobalsWindow
UI + a few more mel commands
Reload/Re-opening the scene
Seems to me that doing the first 2 steps within the scene, it does not rectify the issues in the Render Settings window unless I either close the current scene file by opening a new file session or reopen the file itself...
import maya.cmds as cmds
import maya.mel as mel
def unlockRenderer(renderer="mayaHardware2"):
print "Unlocking and resetting current renderer"
# Unlock the render globals' current renderer attribute
cmds.setAttr("defaultRenderGlobals.currentRenderer", l=False)
# Sets the current renderer to given renderer
cmds.setAttr("defaultRenderGlobals.currentRenderer", renderer, type="string")
def saveFile():
# Prompts User to resave the file, removing traces of Mental Ray
mel.eval('SaveSceneAs;')
def reloadScene():
recentFiles = []
try:
recentFiles = cmds.optionVar( query = 'RecentFilesList' )
except:
cmds.error("No recent files found!")
curFile = cmds.file(query =True, loc = True)
if curFile == "unknown":
cmds.confirmDialog(title = 'Reload Scene', message = ('Reload Last Opened Scene?\n\n' + recentFiles[len(recentFiles)-1]), button = ['Cancel','OK'], defaultButton = 'OK', cancelButton = 'Cancel', dismissString = 'Cancel' )
cmds.file( str(recentFiles[len(recentFiles)-1]), force = True, open = True)
print "Opening Last Recent File - ", recentFiles[len(recentFiles)-1]
else:
cmds.confirmDialog(title = 'Reload Scene', message = ('Reload Current Scene?\n'), button = ['Cancel','OK'], defaultButton = 'OK', cancelButton = 'Cancel', dismissString = 'Cancel' )
curFileLoc = cmds.file(query = True, location = True)
cmds.file( curFileLoc , force = True, open = True)
print "Re-Opening current file - ", curFileLoc
def main():
unlockRenderer(renderer="mayaHardware2")
saveFile()
if cmds.window("unifiedRenderGlobalsWindow", exists=True):
cmds.deleteUI("unifiedRenderGlobalsWindow")
mel.eval('resetAE()')
mel.eval('buildNewSceneUI;')
reloadScene()
main()
Something to note - At times, some errors such as #// Error: file: /apps/Linux64/aw/maya2014/scripts/others/unifiedRenderGlobalsWindow.mel line 1074: setParent: Object 'unifiedRenderGlobalsWindow' not found. // is still encountered, even after the file is reopened. It may differs accordingly to scene file
I've to build a form in QGIS to customize data input for each polygon in the shapefile.
I use QtDesigner to create a form (.ui), with some textboxes and comboboxes pointing to the fields of my shapefile.
Then I use the python file from Nathan QGIS Blog to add some logic.
Python code:
from PyQt4.QtCore import *
from PyQt4.QtGui import *
nameField = None
myDialog = None
def formOpen(dialog,layerid,featureid):
global myDialog
myDialog = dialog
global nameField
nameField = dialog.findChild(QTextEdit,"PART")
buttonBox = dialog.findChild(QDialogButtonBox,"buttonBox")
nameField.textChanged.connect(Name_onTextChanged)
# Disconnect the signal that QGIS has wired up for the dialog to the button box.
buttonBox.accepted.disconnect(myDialog.accept)
# Wire up our own signals.
buttonBox.accepted.connect(validate)
buttonBox.rejected.connect(myDialog.reject)
def validate():
# Make sure that the name field isn't empty.
if not nameField.text().length() > 0:
nameField.setStyleSheet("background-color: rgba(255, 107, 107, 150);")
msgBox = QMessageBox()
msgBox.setText("Field PART must not be NULL.")
msgBox.exec_()
else:
# Return the form as accpeted to QGIS.
myDialog.accept()
def Name_onTextChanged(text):
if not nameField.text().length() > 0:
nameField.setStyleSheet("background-color: rgba(255, 107, 107, 150);")
else:
nameField.setStyleSheet("")
So I open an edit session in QGIS and I click on a polygon with Identify tool, but when I clik on OK button on my customized form, regardless field PART is NULL or not, the following error occurs:
ERROR CODE LINE >>>> if not nameField.text().length() > 0:
ERROR MESSAGE >>>> AttributeError: 'str' object has no attribute 'text'
I'm running QGIS 1.7.4, Python 2.7.2, Windows 7 64-bit.
I miss something... Please, anybody can help me?
It looks like you have a Python error more than a problem with QGIS.
You have two instances of if not nameField.text().length() > 0:
def validate():
if not nameField.text().length() > 0:
and
def Name_onTextChanged(text):
if not nameField.text().length() > 0:
Initially, it looks like nameField is not an input for either of these functions. So I guess these are assigned somewhere else and you've reduced the code example. Also, you have text as a variable input for 'Name_onTextChanged' but you also try and use it as a function 'nameField.text().length()'. This might be a problem.
Generally, Python is complaining because it cannot perform the operation 'text()' on the variable nameField, which it believes is a string. There is no text() function available for strings. And it looks like nameField is actually supposed to be a QTextEdit object.
If nameField is a QTextEdit object, then you can use toPlainText() instead which should do what you need it to do. So something like
if not nameField.toPlainText().strip().length() > 0:
In this instance, I have included .strip() as well so that you do not get a positive result if there are white spaces in text field.
Does that help at all?
I'm trying to create a QueryTable in an excel spreadsheet using the Python comtypes library, but getting a rather uninformative error...
In vba (in a module within the workbook), the following code works fine:
Sub CreateQuery()
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Dim ws As Worksheet
Dim qt As QueryTable
Set ws = ActiveWorkbook.Sheets(1)
Set con = New ADODB.Connection
con.Open ("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Path\to\Db.mdb;")
Set rs = New ADODB.Recordset
rs.Open "Select * from [tbl Base Data];", con
Set qt = ws.QueryTables.Add(rs, ws.Range("A1"))
qt.Refresh
End Sub
But the following Python code:
import sys
import comtypes.client as client
def create_querytable():
constring = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\\Path\\to\\Db.mdb"
conn = client.CreateObject("ADODB.Connection", dynamic = True)
rs = client.CreateObject("ADODB.Recordset", dynamic = True)
SQL = "Select * from [tbl Base Data];"
conn.Open(constring)
rs.Open(SQL, conn)
excel = client.CreateObject("Excel.Application", dynamic = True)
excel.Visible = True
ws = excel.Workbooks.Add().Sheets(1)
qt = ws.QueryTables.Add(rs, ws.Range["A1"])
qt.Refresh()
rs.Close()
conn.Close()
Throws the unhelpful error message:
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
create_querytable()
File "C:/Documents and Settings/cvmne250/Desktop/temp.py", line 17, in create_querytable
qt = ws.QueryTables.Add(rs, ws.Range["A1"])
File "G:\ISA\SPSS\comtypes\lib\comtypes\client\lazybind.py", line 160, in caller
File "G:\ISA\SPSS\comtypes\lib\comtypes\automation.py", line 628, in _invoke
COMError: (-2147352567, 'Exception occurred.', (None, None, None, 0, None))
Any ideas on what's happening here?
Thanks!
I simplified your code and this should work fine (I'll explain the changes below):
def create_querytable2():
constring = "OLEDB;Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\path\to\db.mdb;"
SQL = "Select * from tblName;"
excel = client.CreateObject("Excel.Application", dynamic=True)
excel.Visible = True
ws = excel.Workbooks.Add().Worksheets(1)
ws.QueryTables.Add(constring, ws.Range["A1"], SQL).Refresh()
The QueryTables.Add() function can create the Connection and Recordset objects for you, so that simplifies a lot of things... you just need to add what type of connection it is in the conneciton string (the "OLEDB" part).
Letting Excel do most of the work seems to solve your problem :)
It looks like your error is on this line:
qt = ws.QueryTables.Add(rs, ws.Range["A1"])
I think your problem is that you are using python syntax to look up a value in a VBA Collection. Try changing your square brackets to parentheses.
i.e.
qt = ws.QueryTables.Add(rs, ws.Range("A1"))
The reason being that in VBA when you invoke a Collection like this, Range("A1"), you are actually calling it's default method, Range.Item("A1"). Basically, VBA Collections do not translate to python dictionaries.
I'm getting this from this forum thread, and my experience with VBA.
Edit due to comment:
Unfortunately, I've tried both: as
noted in your link, they sometimes
don't do the same thing, but my gut
feeling here is that the '[' is more
likely to be what I want. – mavnn
Do you know if comtypes.client.CreateObject works the same as win32com.client.Dispatch? You might try creating your com object with the win32com package and see if that makes a difference.