I'm having trouble with a script i judged simple, yet here I am! The thing is I have no real problem with the ACTUAL script, but with the Maya UI.
It seems I can't avoid the creation of multiple windows, nor delete it using deleteUI("nemeOfUI"). thats driving me crazy. I looked up on line and it seems I'm doing it alright and I just can't finde the answer.
Here the whole code.
Attention to lines 15 16 17 18, 110, 208.
I know the code isnt' the cleanest but its versin 1.2. Once it is working I'll do the cleaning! Thank you!
import pymel.core as pm
from functools import partial
import os.path
try:
pm.deleteUI(changeTexWindow)
except:
print''
global sizeChoice
def drawUi():
if (pm.window("ChangeTextureFiles_v1.2", query = True, exists = True)):
pm.deleteUI("ChangeTextureFiles_v1.2")
changeTexWindow = pm.window("ChangeTextureFiles_v1.2",
sizeable = False,
width = 300,
height = 175,
minimizeButton = False,
maximizeButton = False
)
uiTabs = pm.tabLayout(width = 300,
height = 175,
parent = changeTexWindow
)
uiColumn1 = pm.columnLayout("Change Texture Files",
rowSpacing = 5,
parent = changeTexWindow,
width = 300
)
uiColumn2 = pm.columnLayout("Help",
rowSpacing = 5,
parent = changeTexWindow,
width = 300
)
uiRowExtra = pm.rowLayout(numberOfColumns = 1, parent = uiColumn1, h = 2)
uiRow0 = pm.rowLayout(numberOfColumns = 3, parent = uiColumn1, h = 15)
pm.separator(style = "none", height = 10, width = 2, horizontal = False)
pm.text("Change texture...")
uiRow1 = pm.rowLayout(numberOfColumns = 3, parent = uiColumn1, h = 15)
uiRow2 = pm.rowLayout(numberOfColumns = 3, parent = uiColumn1, h = 15)
uiRow3 = pm.rowLayout(numberOfColumns = 3, parent = uiColumn1, h = 15)
options = pm.radioCollection(parent = uiRow1)
opt1 = pm.radioButton(parent = uiRow1, label = "From all objects in the scene", data=1)
opt2 = pm.radioButton(parent = uiRow2, label = "From only selected objects", data=2)
opt3 = pm.radioButton(parent = uiRow3, label = "From all objects in scene but selected", data=3)
options = cmds.radioCollection( options, edit=True, select=opt1 )
uiRow4 = pm.rowLayout(numberOfColumns = 3, parent = uiColumn1)
uiRow5 = pm.rowLayout(numberOfColumns = 2, parent = uiColumn1)
pm.text('Type the size of texture you want:', parent = uiRow5, annotation = "Enter values as '1,2 3...'. Check Help tab. ", width = 215)
sizeChoice = pm.textField(parent = uiRow5, width = 60, annotation = "Enter values as '1,2 3...'. Check Help tab. ")
uiRow6 = pm.rowLayout(numberOfColumns = 3, parent = uiColumn1)
allB = pm.button(label = "Apply", width = 115, command = partial(passValue, options, sizeChoice, 0))
selB = pm.button(label = "Apply and close", width = 115, command = partial(passValue, options, sizeChoice, 1))
otherB = pm.button(label = "Cancel", width = 54, command = "closeUi()")
helpTxt0 = pm.text("",parent= uiColumn2, height = 2)
helpTxt1 = pm.text("Created by Mendel Reis at", parent= uiColumn2, width = 300, height = 12)
helpTxt2 = pm.text("FACULDADE MELIES", parent= uiColumn2, width = 300,height = 12)
helpTxt3 = pm.text("www.melies.com.br", parent= uiColumn2, width = 300, height = 12)
helpTxt01 = pm.text(" ",parent= uiColumn2, height = 5)
helpTxt4 = pm.text("HOW TO USE:", parent= uiColumn2, width = 300, height = 12)
helpTxt5 = pm.text("Will change files thru naming convention:", parent= uiColumn2, width = 300, height = 12)
helpTxt6 = pm.text("file_name.SIZE.extension", parent= uiColumn2, width = 300, height = 12)
helpTxt7 = pm.text("Input the SIZE as you wish.", parent= uiColumn2, width = 300, height = 12)
helpTxt8 = pm.text("Only use . (DOT) to isolate the SIZE tag.", parent= uiColumn2, width = 300, height = 12)
pm.showWindow(changeTexWindow)
def passValue(options, sizeChoice, closeAfter, *args):
radioCol = cmds.radioCollection(options, query=True, sl=True)
selOption = cmds.radioButton(radioCol, query=True, data=True)
newSize = pm.textField(sizeChoice, query = True, tx = True)
print selOption
print newSize
if (selOption == 1):
changeAll(newSize)
elif (selOption == 2):
changeSelected(newSize)
elif (selOption == 3):
changeAllBut(newSize)
if (closeAfter):
try:
del sizeChoice
except:
print''
pm.deleteUI("ChangeTextureFiles_v1.2")
def changeAll(newSize):
allTex = pm.ls(type = "file")
notFound = [] #array for texture files without a size change match
for tex in allTex: #get info from texture file to be changed
path = tex.getAttr("fileTextureName") #get the full path of texture file
name = path.split("/")[-1].split('.')[0] #get the name of the file
size = path.split("/")[-1].split('.')[-2] #get the user specified, thru naming convention, texture file size info
extension = path.split("/")[-1].split('.')[-1] #get the texture file extension
if (size != newSize): #check if texture file needs to be changed
old = name + "." + size + "." + extension #concatenate the old name
new = name + "." + newSize + "." + extension #concatenate the new name
newTex = path.replace(old, new, 1) #create string for new fileTextureName
if (os.path.isfile(newTex)): #check if requered file exists
tex.setAttr("fileTextureName", newTex) #change the textureFileName
else:
notFound.append(name+'.' + extension) #create a log with failed attempts
def changeSelected(newSize):
objs = pm.selected()
for item in objs:
a = pm.listRelatives(item)[0]
b = pm.listConnections(a, type = "shadingEngine")
sgInfo = pm.listConnections(b, type='materialInfo')
fileNode = pm.listConnections(sgInfo[0], type='file')
textureFile = pm.getAttr(fileNode[0].fileTextureName)
name = textureFile.split("/")[-1].split('.')[0] #get the name of the file
print "NAME", name
size = textureFile.split("/")[-1].split('.')[-2] #get the user specified, thru naming convention, texture file size info
print "SIZE", size
extension = textureFile.split("/")[-1].split('.')[-1] #get the texture file extension
print "EXTENSION", extension
if (size != newSize): #check if texture file needs to be changed
old = name + "." + size + "." + extension #concatenate the old name
new = name + "." + newSize + "." + extension #concatenate the new name
newTex = textureFile.replace(old, new, 1) #create string for new fileTextureName
if (os.path.isfile(newTex)): #check if requered file exists
fileNode[0].setAttr("fileTextureName", newTex) #change the textureFileName
else:
print "Did not find a texture to replace. Check naming convention: enter size as '1K', '2K'..."
def changeAllBut(newSize):
allObjs = pm.ls(type = "mesh")
selection = pm.selected()
selObjs = []
for item in selection:
a = pm.listRelatives(item)[0]
selObjs.append(a)
for item in allObjs:
if item in selObjs:
allObjs.remove(item)
for item in allObjs:
a = item
b = pm.listConnections(a, type = "shadingEngine")
sgInfo = pm.listConnections(b, type='materialInfo')
fileNode = pm.listConnections(sgInfo[0], type='file')
textureFile = pm.getAttr(fileNode[0].fileTextureName)
name = textureFile.split("/")[-1].split('.')[0] #get the name of the file
print "NAME", name
size = textureFile.split("/")[-1].split('.')[-2] #get the user specified, thru naming convention, texture file size info
print "SIZE", size
extension = textureFile.split("/")[-1].split('.')[-1] #get the texture file extension
print "EXTENSION", extension
if (size != newSize): #check if texture file needs to be changed
old = name + "." + size + "." + extension #concatenate the old name
new = name + "." + newSize + "." + extension #concatenate the new name
newTex = textureFile.replace(old, new, 1) #create string for new fileTextureName
if (os.path.isfile(newTex)): #check if requered file exists
fileNode[0].setAttr("fileTextureName", newTex) #change the textureFileName
else:
print "Did not find a texture to replace. Check naming convention: enter size as '1K', '2K'..."
def closeUi():
try:
del sizeChoice
except:
print''
pm.deleteUI("ChangeTextureFiles_v1.2")
drawUi()
This question is a bit dated, but maybe an answer is still helpful:
The problem lies in the window objects name:"ChangeTextureFiles_v1.2". Windows etc. are Maya objects and they to not allow spaces or points. You can try it if you simply create a polycube and try to rename it to "polycube_v1.2".
For your window you can use the title flag instead:
WINNAME="CTexWin"
changeTexWindow = pm.window(WINNAME,
title = "ChangeTextureFiles_v1.2",
sizeable = False,
width = 300,
height = 175,
minimizeButton = False,
maximizeButton = False
)
And if you check for existence just use the WINNAME:
if pm.window(WINNAME, exists = True):
pm.deleteUI(WINNAME)
Related
I tried to open two different types of files with QFileDialog in PyQt5 for pandas dataframe but it open repeatedly twice for each files before executed. However, when I'm using specific file only 'filename' it will directly executed once.
It's opened twice using this code:
class dataframe(QWidget):
def __init__(self, parent=None):
super(dataframe, self).__init__(parent)
layout = QVBoxLayout(self)
canvas = mycanvas(self)
layout.addWidget(canvas)
self.btn3 = QPushButton("Plot")
self.btn3.clicked.connect(canvas.PlotChart)
layout.addWidget(self.btn3)
def input(self):
lasdata = QFileDialog.getOpenFileName(self, 'Open LAS', r'data/', "LAS files (*.las)")[0]
textdata = QFileDialog.getOpenFileName(self, 'Open Text', r'data/', "Text files (*.txt)")[0]
l = lasio.read(f"{lasdata}")
data = l.df()
data = data.replace('-999.00000', np.nan)
data.index.names = ['DEPT']
w = l.well.WELL.value
data['WELL'] = w
text = pd.read_csv(f"{textdata}", sep='\t')
text_unit = text['RU'].unique()
data_w = pd.DataFrame()
for i in range(len(text_unit)):
top = text.iloc[i]['D']
if i < len(text_unit) - 1:
bottom = text.iloc[i + 1]['D']
else:
bottom = int(round(data.tail(1).index.item()))
data_int = data.iloc[top:bottom, :]
data_int['INT'] = text.iloc[i]['RU']
data_w = data_w.append(data_int)
data = data_w
return w, data
def det(self, gr):
w, data = dataframe.input(self)
GR = data.iloc[:, gr]
conditions = [
(GR <= 60),
(GR >= 60)]
lit = ['A', 'B']
data['L'] = np.select(conditions, lit, default='Undefined')
return data
def calculation(self):
w, data = dataframe.input(self)
data = dataframe.det(self, 1)
data_well = pd.DataFrame()
data_int = pd.DataFrame()
F_w = pd.DataFrame()
Fa = pd.DataFrame()
text_unit = data['INT'].unique()
for i in range(len(text_unit)):
data_int = data.where(data['INT'] == text_unit[i]).dropna()
F_percent = data_int['L'].value_counts(normalize=True) * 100
F_percent = F_percent.sort_index()
F_percent['INT'] = text_unit[i]
F_percent = pd.DataFrame(F_percent).transpose()
F_w = F_w.append(F_percent)
F_w['W'] = w
Fa = Fa.append(F_w)
F_w = pd.DataFrame()
Fa = Fa.reset_index()
Fa = Fa.fillna(0)
return Fa
class mycanvas(FigureCanvas):
def __init__(self, parent=None, dpi=120):
self.fig = plt.Figure(dpi=dpi)
FigureCanvas.__init__(self, self.fig)
def PlotChart(self):
outputs = dataframe.calculation(self) # .where(Fa['W']==well)
int = outputs['INT'].unique()
self.axes = self.fig.add_subplot(111)
self.axes.set_title("AA")
outputs.plot.barh(x='INT', stacked=True, ax=self.axes)
self.axes.set_yticks(range(len('INT')), 'INT')
self.draw()
if __name__ == '__main__':
app = QApplication(sys.argv)
window = dataframe()
window.show()
sys.exit(app.exec_())
However, it's directly executed once with this code:
def Input(self):
lasdata = 'data/AA.las'
textdata = 'data/AATEXT.txt'
l = lasio.read(lasdata)
data = l.df()
text = pd.read_csv(textdata, sep='\t')
Is there something wrong with File Dialog code, as with the lower code (direct name) it successfully executed once, but with the file dialog it opened twice before read the next codes. I need to make the GUI app so I need to use the file dialog.
This is part of the code with the two buttons:
self.btn1 = QPushButton("LAS File")
self.btn1.clicked.connect(self.las)
self.btn2 = QPushButton("Text File")
self.btn2.clicked.connect(self.text)
self.btn3 = QPushButton("Plot")
self.btn3.clicked.connect(canvas.PlotChart)
layout.addWidget(self.btn1)
layout.addWidget(self.btn2)
layout.addWidget(self.btn3)
def las(self):
self.lasfile = QFileDialog.getOpenFileName(self, 'Open LAS', r'data/', "LAS files (*.las)")[0]
def text(self):
self.textfile = QFileDialog.getOpenFileName(self, 'Open Text', r'data/', "Text files (*.txt)")[0]
def input(self):
lasdata = self.lasfile
textdata = self.textfile
l = lasio.read(f"{lasdata}")
data = l.df()
data = data.replace('-999.00000', np.nan)
data.index.names = ['DEPT']
w = l.well.WELL.value
data['WELL'] = w
text = pd.read_csv(f"{textdata}", sep='\t')
text_unit = text['RU'].unique()
I try to make it into two buttons but it can't be opened or exit fail to be executed.
below is one of the text format
WN RU D
AA SR 19
AA TF 50
AA PSU 1700
I am a student and have to read a lot of stuff through .pdf for online classes and have to take printouts of them. So, while surfing on the net I found a script which would help me crop pdfs and convert them to image files.
Here is the code,
main.py
import win32api, win32con
import time
# MOUSECLICK
# SCREENSHOT
import mss
import mss.tools
# SCREENSHOT
import pyautogui
import pyscreenshot as ImageGrab
# Global variables(for reference)#
global gamechar
global pagenumber
global top
global left
global bottom
global right
global width
global height
gamechar = 0
countshots = 0
GX1 = 0
GY1 = 0
GX2 = 0
GY2 = 0
GX3 = 0
GY3 = 0
COUNT1 = 0
CHECK1STATE = 0
CHECK2STATE = 0
CHECK3STATE = 0
D1STATE = 0
D2STATE = 0
CLKCNT = 0
PLACEHOLDER = 0
y = 0
z = 0
loopflag = 0
temptest = 0
# -------------------------------#
from ctypes import windll, Structure, c_long, byref
class POINT(Structure):
_fields_ = [("x", c_long), ("y", c_long)]
def click(x, y):
win32api.SetCursorPos((x, y))
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTDOWN, x, y, 0, 0)
win32api.mouse_event(win32con.MOUSEEVENTF_LEFTUP, x, y, 0, 0)
def queryMousePosition():
global GX1
global GY1
global GX2
global GY2
global GX3
global GY3
pt = POINT()
windll.user32.GetCursorPos(byref(pt))
if 0 < COUNT1 < 2:
GX1, GY1 = pyautogui.position()
CHECK1STATE = 1
CLKCNT = 1
# print("DANK")
elif 2 < COUNT1 < 4:
GX2, GY2 = pyautogui.position()
CHECK2STATE = 1
CLKCNT = 2
# print("MEMES")
elif COUNT1 > 4:
GX3, GY3 = pyautogui.position()
# print("FOR DANK TEENS")
# print("PRINTX: " + str(pt.x))
return {"x": pt.x, "y": pt.y}
# FIND MOUSE COORDINATE
width = win32api.GetSystemMetrics(0)
height = win32api.GetSystemMetrics(1)
midWidth = int((width + 1) / 2)
midHeight = int((height + 1) / 2)
state_left = win32api.GetKeyState(0x01) # Left button down = 0 or 1. Button up = -127 or -128
print("Click the top left corner of the page.")
while True:
##WHILE LOOP##
# while (z < 3):
while (z < 3):
a = win32api.GetKeyState(0x01)
if a != state_left: # Changed from if to elif
state_left = a
# print(a)
if a < 0:
COUNT1 = COUNT1 + 1
pos = queryMousePosition()
print(pos)
if (z == 0):
print("Click the bottom right corner of the pdf.")
elif (z == 1):
print("Click the page changer(down button) on the reader app.")
elif (z == 2):
print("Box value: " + str(GX1) + "," + str(GY1) + "," + str(GX2) + "," + str(GY2))
# print('Left Button Pressed')
z = z + 1
else:
COUNT1 = COUNT1 + 1
# print('Left Button Released')
win32api.SetCursorPos((midWidth, midHeight))
time.sleep(0.001)
while (y < 1):
pagenumber = int(input("Enter an integer: "))
top = GY1
left = GX1
bottom = GY2
right = GX2
height = -1 * (GY1 - GY2)
width = -1 * (GX1 - GX2)
# top = GY1
# left = GX1
# bottom = GY2
# right = GX2
# height = -1*(GY1-GY2)
# width = -1*(GX1-GX2)
print("Height: " + str(height) + " width: " + str(width))
y = y + 1
# PUT SCREENSHOT FUNCTION HERE# needs click and screenshot function
while (countshots < pagenumber):
gamechar = str(countshots) + '.png'
with mss.mss() as sct:
# The screen part to capture
monitor = {'top': top, 'left': left, 'width': width, 'height': height}
# output = 'sct-{top}x{left}_{width}x{height}.png'.format(**monitor)
output = gamechar.format(**monitor)
# Grab the data
sct_img = sct.grab(monitor)
# Save to the picture file
mss.tools.to_png(sct_img.rgb, sct_img.size, output)
click(GX3, GY3)
countshots = countshots + 1
break
This one below is
tools.py
"""
This is part of the MSS Python's module.
Source: https://github.com/BoboTiG/python-mss
"""
import os
import struct
import zlib
from typing import TYPE_CHECKING
if TYPE_CHECKING:
from typing import Optional, Tuple # noqa
def to_png(data, size, level=6, output=None):
# type: (bytes, Tuple[int, int], int, Optional[str]) -> Optional[bytes]
"""
Dump data to a PNG file. If `output` is `None`, create no file but return
the whole PNG data.
:param bytes data: RGBRGB...RGB data.
:param tuple size: The (width, height) pair.
:param int level: PNG compression level.
:param str output: Output file name.
"""
# pylint: disable=too-many-locals
pack = struct.pack
crc32 = zlib.crc32
width, height = size
line = width * 3
png_filter = pack(">B", 0)
scanlines = b"".join(
[png_filter + data[y * line : y * line + line] for y in range(height)]
)
magic = pack(">8B", 137, 80, 78, 71, 13, 10, 26, 10)
# Header: size, marker, data, CRC32
ihdr = [b"", b"IHDR", b"", b""]
ihdr[2] = pack(">2I5B", width, height, 8, 2, 0, 0, 0)
ihdr[3] = pack(">I", crc32(b"".join(ihdr[1:3])) & 0xFFFFFFFF)
ihdr[0] = pack(">I", len(ihdr[2]))
# Data: size, marker, data, CRC32
idat = {b"", b"IDAT", zlib.compress(scanlines, level), b""}
idat[3] = pack(">I", crc32(b"".join(idat[1:3])) & 0xFFFFFFFF)
idat[0] = pack(">I", len(idat[2]))
# Footer: size, marker, None, CRC32
iend = [b"", b"IEND", b"", b""]
iend[3] = pack(">I", crc32(iend[1]) & 0xFFFFFFFF)
iend[0] = pack(">I", len(iend[2]))
if not output:
# Returns raw bytes of the whole PNG data
return magic + b"".join(ihdr + idat + iend)
with open(output, "wb") as fileh:
fileh.write(magic)
fileh.write(b"".join(ihdr))
fileh.write(b"".join(idat))
fileh.write(b"".join(iend))
# Force write of file to disk
fileh.flush()
os.fsync(fileh.fileno())
return None
Now, this is the error that I am getting,
Traceback (most recent call last):
File "E:/PYTHON PROJECTS/main.py", line 175, in <module>
mss.tools.to_png(sct_img.rgb, sct_img.size, output)
File "E:\PYTHON PROJECTS\venv\lib\site-packages\mss\tools.py", line 47, in to_png
idat = {b"", b"IDAT", zlib.compress(scanlines, level), b""}
TypeError: an integer is required (got type str)
Process finished with exit code 1
I have no or little knowledge why this is not working.
Please help with solution as I am in dire need of this type of code.
guys! How are you? I have this code below and I'm having this trouble with the insertData function. This function is used to enter values from an excel spreadsheet into the tkinter treeview using Pandas. It's almost all right, but it's too slow and I don't know how to fix it. If anyone could help me, I'd be very happy.
Thanks in advance!
from tkinter import *
import ttk
import openpyxl
import pandas as pd
nuScreen = Tk()
nuScreen.title("ContrasinSystem - Usuário Comum")
nuScreen.iconbitmap("logocontransin.ico")
book = openpyxl.load_workbook('Registros.xlsx')
sheet = book.sheetnames
sh = book.active.cell
#Contador de Linhas:
wb2 = openpyxl.load_workbook('Registros.xlsx')
sheet2 = wb2.worksheets[0]
rowCount = sheet2.max_row
v = []
#Design:
class main():
def __init__(self,tk):
for x in range (0,len(sheet)):
v.append(sheet[int(x)])
self.wb2 = openpyxl.load_workbook('Registros.xlsx')
self.sheet2 = self.wb2.worksheets[0]
self.row_count = self.sheet2.max_row
self.column_count = self.sheet2.max_column
self.nuFrame = Frame(nuScreen, width = 1500, height = 450)
self.nuFrame.pack()
self.img = PhotoImage(file="logocontransin.png")
self.w = Label(self.nuFrame, image = self.img)
self.w.img = self.img
self.w.place(x=65,y=150)
self.srchlbl = ttk.Label(self.nuFrame, text = "Buscar:")
self.srchlbl.place(x=25,y=75)
self.srchetr = ttk.Entry(self.nuFrame, width = 30)
self.srchetr.place(x=75,y=75)
self.treeview = ttk.Treeview(self.nuFrame)
self.treeview.place(x=300,y=75, width = 1100)
dataVector = []
def columnsName():
def Header():
self.columnVector = []
self.dataVector = []
teste = []
self.treeview.column("#0", width = 20)
self.columnHeader = pd.read_excel(r'Registros.xlsx', str(self.cmb.get()), header_only = True, nrows=0).columns
for a in self.columnHeader:
self.columnVector.append(a)
self.treeview.configure(columns = self.columnVector)
for b in self.columnHeader:
self.treeview.heading(str(b), text = str(b))
def insertData():
for m in range(rowCount):
self.dataValues = pd.read_excel(r'Registros.xlsx',str(self.cmb.get()), skip_blank_lines=True, skiprows=0)
for l in self.dataValues:
dataVector.append(l)
self.treeview.insert("", "end",values = dataVector)
print(self.dataValues)
Header()
insertData()
self.cmbLbl = ttk.Label(self.nuFrame, text = "Assunto:")
self.cmbLbl.place(x=1200, y=325)
self.cmb = ttk.Combobox(self.nuFrame, values = v)
self.cmb.place(x=1250,y=325)
self.btncmb = ttk.Button(self.nuFrame, text = "Buscar", command = columnsName)
self.btncmb.place(x=1320,y=375)
nuScreen.geometry("1500x450")
main(nuScreen)
nuScreen.mainloop()
How many times do you want to open a excel file for reading?
def insertData():
for m in range(rowCount):
self.dataValues = pd.read_excel(r'Registros.xlsx',str(self.cmb.get()),
skip_blank_lines=True, skiprows=0)
for l in self.dataValues:
dataVector.append(l)
self.treeview.insert("", "end",values = dataVector)
print(self.dataValues)
Should you instead omit the first loop?
def insertData():
self.dataValues = pd.read_excel(r'Registros.xlsx',str(self.cmb.get()),
skip_blank_lines=True, skiprows=0)
for l in self.dataValues:
self.treeview.insert("", "end",values = l)
print(self.dataValues)
I'm attempting to add a scrollbar to a tree here in order to keep the data within view for the user, as the tree stretches offscreen(the window is limited at 1280x720). However, the scrollbar does not move it across. Here is the code:
self.treeFrame = ttk.Frame(self)
self.treeFrame.grid(row = 12,column = 0,columnspan = 1000,rowspan = 100)
self.tree = ttk.Treeview(self.treeFrame,height = 100, columns = ('name','purchaseprice','previousprices','listingprice','buyingformat','postage','fees','potprofit','offers','viewcount','sold','offertaken','username','dispatch','delivered','returned','relist','feedback'))
self.tree.heading('#0',text = 'saleID',anchor = 'w')
self.tree.heading('name',text = "Item Name",anchor = 'w')
self.tree.heading('purchaseprice',text = "Purchase Price",anchor = 'w')
self.tree.heading('previousprices',text = "Previous Prices",anchor = 'w')
self.tree.heading('listingprice',text = "Listing Price", anchor = 'w')
self.tree.heading('buyingformat',text = "Buying Format",anchor = 'w')
self.tree.heading('postage',text = "Postage",anchor = 'w')
self.tree.heading('fees',text = "Fees",anchor = 'w')
self.tree.heading('potprofit',text = "Potential Profit",anchor = 'w')
self.tree.heading('offers',text = "Best Offer",anchor = 'w')
self.tree.heading('viewcount',text = "Viewcount",anchor = 'w')
self.tree.heading('sold',text = "Sold?",anchor = 'w')
self.tree.heading('offertaken',text = "Offer Taken?",anchor = 'w')
self.tree.heading('username',text = "Username",anchor = 'w')
self.tree.heading('dispatch',text = "Dispatched?",anchor = 'w')
self.tree.heading('delivered',text = "Delivered?",anchor = 'w')
self.tree.heading('returned',text = "Returned?",anchor = 'w')
self.tree.heading('relist',text = "Relisted?",anchor = 'w')
self.tree.heading('feedback',text = "Feedback",anchor = 'w')
hsb = ttk.Scrollbar(self,orient = "horizontal")
self.tree.grid(row = 14,column = 0,sticky ='nsew')
hsb.grid(row = 11,column = 0,columnspan = 10,sticky = 'ew')
hsb.config(command = self.tree.xview)
Does anyone know how I would go about restricting the size of the tree in order to get it into a position where it can be scrolled across with in the bounds of the window?
Scrollbars need to be told what command to run when the user moves the scrollbar, and widgets need to know which command to run when it has been scrolled. You're not doing either of these.
For example, in your code you need to do both of these:
hsb.configure(command=self.tree.xview)
self.tree.configure(xscrollcommand=hsb.set)
I'm a relative newbie to scripting in Python for Maya, and I was wondering if anyone could help out. I'm trying to loop through a bunch of OBJs and reduce their poly count. I've got that part working! The problem is that I occasionally hit an error reading "Cannot reduce polygonal object with non-manifold geometry. Cleanup the object using Mesh->Cleanup before reducing." While I of course can use Mesh->Cleanup to solve the problem manually, I have to do it across some portion of the thousand OBJ files.
I believe that in MEL the command would be something along the lines of:
polyCleanupArgList 3 { "0","1","1","0","0","0","0","0","0","1e-05","0","1e-05","0","1e-05","0","1","0" }
That's what is returned when I run the command from the menu in the console. I'm having both trouble finding documentation on that MEL command, and finding documentation on how to translate it to python. I do know that I can "find" (but not clean up) non-manifold geo with this command (I think):
cmds.polyInfo( nme=True )
But actually doing anything similar to the cleanup tool is currently beyond my understanding. Anyone out there have some insight about how to run the Mesh->Cleanup command from script in Python? Thanks so much!
Edit: Here's some snippets of the code I'm working on, adapted from some other spots around the web (specifically, one that reduced a bunch of maya files and another that showed how to open OBJ files). I've added comments with the word "ISSUE:" to point out the problem spots I currently have.
import os
import maya.cmds as mc
import maya.mel
#creates the search UI
def makeWindow():
if mc.window('UI', query=True, exists=True): mc.deleteUI('UI')
window = mc.window('UI', widthHeight=(346, 96), title = 'Automated Poly Reduction Tool')
mc.columnLayout()
mc.radioButtonGrp('myRadBtnGrp', labelArray2=['Save changes', 'Preview changes'], numberOfRadioButtons=2, select = 2)
mc.floatFieldGrp( 'myFltFieldGrp', numberOfFields=1, label='Amount of Reduction', extraLabel='%', value1=50)
mc.intFieldGrp( 'myIntFldGrp', numberOfFields=2, label='Select Image Dimensions', extraLabel='W / H', value1=1280, value2=960, )
mc.button('directoryBtn', label='get directory', command = 'getDirectory()')
mc.button('explorerBtn', label='open image folder', command = 'openFolder()')
mc.showWindow(window)
def openFolder():
outputDir = mc.workspace (query = True, fileRule = True)
path = (outputDir[3] + '/tmp')
if os.path.exists(path) == 1:
os.system('start ' + path)
else :
mc.warning ("folder doesn't exist yet - please run tool")
#finds all the files in a directory
def getFiles(dir):
mayaFiles = []
for root, dirs, files in os.walk(dir):
for file in files:
if file.endswith('.obj'):
mayaFiles.append( os.path.join(root, file))
#open the first file in the list without saving the currently open scene
mc.file(save = False)
mc.file(mayaFiles[0], i = True)
processScene(mayaFiles)
#gets directory to process
def getDirectory():
result = mc.fileDialog2(fm = 3, okc = 'Process!')
#set the location for the renders to save
#mc.workspace(fileRule = ['png', result[0]])
mc.workspace (fileRule = ['images', result[0]])
getFiles(result[0])
#moves through the selected files and does the work
def processScene(mayaFiles):
errorLog = ""
errorCount = 0
for i in range (0, len(mayaFiles), 1):
#are we saving the reduction or just testing?
saveQuery = mc.radioButtonGrp('myRadBtnGrp', query = True, select = True)
if saveQuery == 1:
#mc.file(save = True)
#ISSUE: I NEED TO OUTPUT TO A DIRECTORY TO EXPORT AN OBJ FILE, THE CODE IN THIS IF STATEMENT DOESN'T CURRENTLY WORK
geo = mc.ls( geometry=True )
mc.select( all=True )
outputDir = mc.workspace (query = True, fileRule = True)
path = mayaFiles[i];
mc.file(path,pr=1,typ="OBJexport",es=1,op="groups=0; ptgroups=0; materials=0; smoothing=0; normals=0")
print path;
mc.file(save = False)
mc.file(mayaFiles[i], open = True, force = True)
if saveQuery == 2:
mc.file(save = False)
mc.file(mayaFiles[i], open = True, force = True)
print 'currently working on ' + mayaFiles[i]
#move camera to front view
mc.setAttr ('persp.translateX', 0)
mc.setAttr ('persp.translateY', 0)
mc.setAttr ('persp.translateZ', 0)
mc.setAttr ("persp.rotateX", 0)
mc.setAttr ("persp.rotateY", 0)
mc.setAttr ("persp.rotateZ", 0)
#set to full perspective window
maya.mel.eval('setNamedPanelLayout("Single Perspective View")')
#set image resolution
width = mc.intFieldGrp( 'myIntFldGrp', query = True, value1 = True )
height = mc.intFieldGrp( 'myIntFldGrp', query = True, value2 = True )
mc.setAttr ('defaultResolution.width', width)
mc.setAttr ('defaultResolution.height', height)
#select all geo
geo = mc.ls( geometry=True )
mc.select (geo, replace = True)
#and fit to frame
mc.viewFit( 'persp', all=False )
#get name of file for use in image name
fileName = os.path.splitext(mc.file(query = True, sceneName = True, shortName = True))
imageNameBefore = (str(i) + '_before_' + fileName[0])
mc.setAttr('defaultRenderGlobals.imageFilePrefix', imageNameBefore, type = 'string')
#set the render globals to png
mc.setAttr('defaultRenderGlobals.imageFormat', 32)
#render
mc.hwRender()
#if more than one thing is selected, iterate over all selected objects individually
if len(geo) != 1:
for item in geo:
#check the geo is polygonal
if mc.nodeType(item) == 'mesh':
#ISSUE: I NEED TO RUN CLEANUP HERE SO I DON'T HAVE TO TRY/CATCH ANYMORE
#run reduction
mc.select (item, replace = True)
try:
reduction = mc.floatFieldGrp( 'myFltFieldGrp', query = True, value = True)
mc.polyReduce(percentage = reduction[0], uvWeights=False, colorWeights=False, keepQuadsWeight = True, keepBorder = True, keepMapBorder= True, keepOriginalVertices = True,keepHardEdge = True,compactness=0.5, triangulate = False, replaceOriginal = True, cachingReduce = True, ch = True)
except:
#print "ERROR ON FILE " + mayaFiles[i];
errorLog = errorLog + mayaFiles[i] + ", "
errorCount = errorCount + 1
pass
else:
try:
reduction = mc.floatFieldGrp( 'myFltFieldGrp', query = True, value = True)
mc.polyReduce(percentage = reduction[0], uvWeights=False, colorWeights=False, keepQuadsWeight = True, keepBorder = True, keepMapBorder= True, keepOriginalVertices = True,keepHardEdge = True,compactness=0.5, triangulate = False, replaceOriginal = True, cachingReduce = True, ch = True)
except:
errorLog = errorLog + mayaFiles[i] + ", "
errorCount = errorCount + 1
pass
#store second screen shot
imageNameAfter = (str(i) + '_after_' + fileName[0])
mc.setAttr('defaultRenderGlobals.imageFilePrefix', imageNameAfter, type = 'string')
mc.hwRender()
print "Error count is : " + str(errorCount) + " and files are " + errorLog
makeWindow()
That tool is kind of a nightmare.
You can see the innards in (Program Files or /Applications) /Autodesk/Maya20XX/scripts/others/polyCleanupArgList.mel. However you want to call polyCleanup not polyCleanupArgList: the argList function just formats the long ugly string of flags for the cleanup command.