Dynamically generate pygtk menu's based on dictionaries and lists - python

I have a list of options that I read from an xml file. In the list there is information like codenames, item relations, child codenames ...
I use the following functions to generate pygtk boxes with the proper buttons in it. My problem is that I have to be able to hide/show those boxes at some points (one example would be self.btn_box_web.show()/hide().
How could I better generate my menu's or access them ?
I first generate a list of server install type and make a box with proper buttons in it
def build_custom_server(self, server_type_dict, component_dict):
self.custom_server_box = gtk.VBox(False, 0)
self.option_box.pack_start(self.custom_server_box, False)
self.custom_server_box.set_border_width(10)
self.custom_server_label = gtk.Label("Customize your server instalation:")
self.custom_server_box.pack_start(self.custom_server_label, True)
self.type_box = gtk.HBox(True, 0)
self.custom_server_box.pack_start(self.type_box, False)
self.type_label = gtk.Label("Server type:")
self.type_box.pack_start(self.type_label, True)
for stype in server_type_dict:
self.btn_name = "self.btn_" + stype
self.img_name = "self.img_" + stype
self.label_name = "self.label_" + stype
self.box_name = "self.btn_box_" + stype
vars()[self.btn_name] = gtk.ToggleButton()
vars()[self.box_name] = gtk.VBox(False, 0)
vars()[self.img_name] = gtk.Image()
vars()[self.img_name].set_from_file("art/" + stype + ".png")
vars()[self.label_name] = gtk.Label(server_type_dict[stype])
vars()[self.box_name].pack_start(vars()[self.img_name], False)
vars()[self.box_name].pack_end(vars()[self.label_name], False)
vars()[self.btn_name].add(vars()[self.box_name])
self.type_box.pack_start(vars()[self.btn_name], True)
self.load_type(server_type_dict, component_dict, stype)
Then for each type (type can be in 2 fields since we have main categories and secondaries) I generate a separate box with the components.
def load_type(self, server_type_dict, component_dict, stype):
self.up_label_name = "self.label_" + stype
self.up_box_name = "self.btn_box_" + stype
vars()[self.up_box_name] = gtk.HBox(False, 0)
vars()[self.up_label_name] = gtk.Label(server_type_dict[stype])
vars()[self.up_box_name].pack_start(vars()[self.up_label_name], False)
self.custom_server_box.pack_start(vars()[self.up_box_name], False)
for compo in component_dict:
if component_dict[compo][1] == stype:
self.btn_name = "self.btn_" + compo
self.img_name = "self.img_" + compo
self.label_name = "self.label_" + compo
self.box_name = "self.btn_box_" + compo
vars()[self.btn_name] = gtk.ToggleButton()
vars()[self.box_name] = gtk.VBox(False, 0)
vars()[self.img_name] = gtk.Image()
vars()[self.img_name].set_from_file("art/" + compo + ".png")
vars()[self.label_name] = gtk.Label(component_dict[compo][0])
vars()[self.box_name].pack_start(vars()[self.img_name], False)
vars()[self.box_name].pack_end(vars()[self.label_name], False)
vars()[self.btn_name].add(vars()[self.box_name])
vars()[self.up_box_name].pack_start(vars()[self.btn_name], True)
elif component_dict[compo][2] == stype:
self.btn_name = "self.btn_" + compo
self.img_name = "self.img_" + compo
self.label_name = "self.label_" + compo
self.box_name = "self.btn_box_" + compo
vars()[self.btn_name] = gtk.ToggleButton()
vars()[self.box_name] = gtk.VBox(False, 0)
vars()[self.img_name] = gtk.Image()
vars()[self.img_name].set_from_file("art/" + compo + ".png")
vars()[self.label_name] = gtk.Label(component_dict[compo][0])
vars()[self.box_name].pack_start(vars()[self.img_name], False)
vars()[self.box_name].pack_end(vars()[self.label_name], False)
vars()[self.btn_name].add(vars()[self.box_name])
vars()[self.up_box_name].pack_start(vars()[self.btn_name], True)
My full code can be found here

That's a lot of code to go through, so I'm not entirely sure that I know exactly what you want to do. I can think of a couple of ways that you can later access these dynamically created widgets, though.
One would be to use widget.set_name() to give each widget a name. You could then later get all the child widgets and iterate over them looking for the one with that name. If you have a lot of widgets, this might be slow. It might be easier to just keep a dict() object keyed with the names you get from the config file, which you could then dynamically access later. ie, something like:
widgets = {}
for stype in server_type_dict:
widgets[stype] = {}
widgets[stype]['btn'] = gtk.ToggleButton()
widgets[stype]['box'] = gtk.VBox(False, 0)
widgets[stype]['img'] = gtk.Image()
...
self.type_box.pack_start(widgets[stype]['btn'], True)
self.load_type(server_type_dict, component_dict, stype)
...and so on.
Later, if you need the "web" server-type button, you would just call widgets['web']['btn']

Related

Same Python code, same Data, outcomes different if Data imported or not?

So I have a Python code that first aggregates and standardizes Data into a file I called "tripFile". Then the code tries to identify the differences between this most recent tripFile and a previous one.
From the first part of the code, if I export the tripFile, and import it again for the second part of the code, it takes around 5 minutes to run and says it is looping over a bit more than 4,000 objects.
newTripFile = pd.read_csv(PATH + today + ' Trip File v6.csv')
However, if I do not export & re-import the Data (just keeping it from the first part of the code), it takes a bit less than 24 hours (!!) and says it is looping over a bit more than 951,691 objects.
newTripFile = tripFile
My Data is a dataframe, and checked the shape of it, it is identical to the file I export.
Any idea what can be causing that ???
Here is the second part of my code:
oldTripFile = pd.read_excel(PATH + OLDTRIPFILE)
oldTripFile.drop(['id'], axis = 1, inplace = True)
oldTripFile['status'] = 'old'
# New version of trip file
newTripFile = pd.read_csv(PATH + today + ' Trip File v6.csv')
newTripFile.drop(['id'], axis = 1, inplace = True)
newTripFile['status'] = 'new'
db_trips = pd.concat([oldTripFile, newTripFile]) #concatenation of the two dataframes
db_trips = db_trips.reset_index(drop = True)
db_trips.drop_duplicates(keep = False, subset = [column for column in db_trips.columns[:-1] ], inplace = True)
db_trips = db_trips.reset_index(drop = True)
db_trips.head()
update_details = []
# Get the duplicates : only consider ['fromCode', 'toCode', 'mode'] for identifying duplicates
# Create a dataframe that contains only the trips that was deleted and was recently added
db_trips_delete_new = db_trips.drop_duplicates(keep = False, subset = ['fromCode', 'toCode', 'mode'])
db_trips_delete_new = db_trips_delete_new.reset_index(drop = True)
# New trips
new_trips = db_trips_delete_new[db_trips_delete_new['status'] == 'new'].values.tolist()
for trip in new_trips:
trip.append('new trip added')
update_details = update_details + new_trips
# Deleted trips
old_trips = db_trips_delete_new[db_trips_delete_new['status'] == 'old'].values.tolist()
for trip in old_trips:
trip.append('trip deleted')
update_details = update_details + old_trips
db_trips_delete_new.head()
# Updated trips
# Ocean: no need to check the transit time column
sea_trips = db_trips.loc[db_trips['mode'].isin(['sea', 'cfs'])]
sea_trips = sea_trips.reset_index(drop = True)
list_trips_sea_update = sea_trips[sea_trips.duplicated(subset = ['fromCode', 'toCode', 'mode'], keep = False)].values.tolist()
if len(list_trips_sea_update) != 0:
for i in tqdm(range(0, len(list_trips_sea_update) - 1)):
for j in range(i + 1, len(list_trips_sea_update)):
if list_trips_sea_update[i][2] == list_trips_sea_update[j][2] and list_trips_sea_update[i][9] == list_trips_sea_update[j][9] and list_trips_sea_update[i][14] == list_trips_sea_update[j][14]:
update_comment = ''
# Check display from / to
if list_trips_sea_update[i][5] != list_trips_sea_update[j][5]:
update_comment = update_comment + 'fromDisplayLocation was updated.'
if list_trips_sea_update[i][12] != list_trips_sea_update[j][12]:
update_comment = update_comment + 'toDisplayLocation was updated.'
# Get the updated trip (the row with status new)
if list_trips_sea_update[i][17] == 'new' and list_trips_sea_update[j][17] != 'new' :
list_trips_sea_update[i].append(update_comment)
update_details = update_details + [list_trips_sea_update[i]]
else:
if list_trips_sea_update[j][17] == 'new' and list_trips_sea_update[i][17] != 'new':
list_trips_sea_update[j].append(update_comment)
update_details = update_details + [list_trips_sea_update[j]]
else:
print('excel files are not organized')
# Ground: transit time column need to be checked
ground_trips = db_trips[~db_trips['mode'].isin(['sea', 'cfs'])]
ground_trips = ground_trips.reset_index(drop = True)
list_trips_ground_update = ground_trips[ground_trips.duplicated(subset = ['fromCode', 'toCode', 'mode'], keep = False)].values.tolist()
if len(list_trips_ground_update) != 0:
for i in tqdm(range(0, len(list_trips_ground_update) - 1)):
for j in range(i + 1, len(list_trips_ground_update)):
if list_trips_ground_update[i][2] == list_trips_ground_update[j][2] and list_trips_ground_update[i][9] == list_trips_ground_update[j][9] and list_trips_ground_update[i][14] == list_trips_ground_update[j][14]:
update_comment = ''
# Check display from / to
if list_trips_ground_update[i][5] != list_trips_ground_update[j][5]:
update_comment = update_comment + 'fromDisplayLocation was updated.'
if list_trips_ground_update[i][12] != list_trips_ground_update[j][12]:
update_comment = update_comment + 'toDisplayLocation was updated.'
# Check transit time
if list_trips_ground_update[i][15] != list_trips_ground_update[j][15]:
update_comment = update_comment + 'transit time was updated.'
# Get the updated trip (the row with status new)
if list_trips_ground_update[i][17] == 'new' and list_trips_ground_update[j][17] != 'new' :
list_trips_ground_update[i].append(update_comment)
update_details=update_details + [list_trips_ground_update[i]]
else:
if list_trips_ground_update[j][17] == 'new' and list_trips_ground_update[i][17] != 'new':
list_trips_ground_update[j].append(update_comment)
update_details = update_details + [list_trips_ground_update[j]]
else:
print('excel files are not organized')
And here an example of what my trip file looks like:
Any help is appreciated :)
If ever it can be useful to someone else, issue was coming from the type. When keeping my tripFile in memory, one of my column was "10.0" for example, whereas when imported this column was "10".
As I'm comparing with another imported tripFile, if both files are imported the column in both files are of same type, but if one of the files is kept in memory the column is of different type in both files and considered as updated. As such takes much longer when kept in memory as every row is considered updated.

How do you query an object inside of a text field, to do something with it?

I would like to know how to query a selection entered into a text field group, so I can do something with it. I have created a window to just translate an object that I loaded in the text field. The error is that cont is not defined.
import maya.cmds as cmds
import maya.mel as ml
def set_selected_name (text_field):
cont = cmds.ls (selection = True)
text_field = cmds.textFieldButtonGrp (text_field, edit = True,
text = ''.join (cont),
buttonLabel = '<<<<',
backgroundColor = [0.5098039215686274,
0.5098039215686274,
0.5098039215686274])
return text_field
def translate_x(cont):
cmds.setAttr( cont[0] + '.translateX', 10)
def translate_y():
cmds.setAttr( cont[0] + '.translateY', 10)
def translate_z(*Args):
cmds.setAttr( cont[0] + '.translateZ', 10)
if cmds.window ('window1', q = 1, ex = 1):
cmds.deleteUI ('window1')
cmds.window ('window1',
title = 'Translate Attr',
sizeable = 0,
resizeToFitChildren = True,
menuBar = 1)
cmds.rowLayout (numberOfColumns = 3)
cmds.separator (style = 'double',
height = 6)
cmds.rowLayout (parent = 'window1',
numberOfColumns = 4)
ddd = cmds.textFieldButtonGrp (editable = False,
text = 'Obj',
backgroundColor = [0.029495689326314183,
0.5488975356679637,
0.5488975356679637],
buttonLabel = '<<<<')
cmds.textFieldButtonGrp (ddd, edit = True,
buttonCommand = 'set_selected_name (ddd)')
cmds.separator (style = 'double',
height = 6)
cmds.rowLayout (parent = 'window1',
numberOfColumns = 6)
cmds.separator (style = 'double',
height = 6)
cmds.button (command = 'translate_y()',
backgroundColor = [1.0,
0.7300068665598535,
0.7300068665598535],
label = 'Translate Y')
cmds.separator (style = 'double',
height = 6)
cmds.button (command = 'translate_x(cont)',
backgroundColor = [1.0,
0.9733272297245746,
0.7333333333333333],
label = 'Translate X')
cmds.separator (style = 'double',
height = 6)
cmds.button (command = 'translate_z()',
backgroundColor = [0.7333333333333333,
1.0,
0.7600061036087586],
label = 'Translate Z')
cmds.columnLayout (parent = 'window1')
cmds.separator (style = 'double',
height = 3)
cmds.showWindow ('window1')
# ~ BABLAAM ~
Create any object you like, loaded into the text field and then try to translate with buttons.
You have several problems in your code.
In the translate commands you always use cont[0]. cont is only used in the function set_selected_name() and is a local variable what means it is deleted as soon as the function is completed.
You can use a string as command in the button command, but this only works with static values. You should use lambdas to use functions with arguments.
The cont Problem can be solved by using a global variable, but it shouldn't since global variables are the source of all evil. A much more elegant way would be to enclose you UI in one python class and use instance variables to get the selection.
I have adjusted the code to add the class as you recommended but still having the same issue. By not using the quotes in the button command I get this error when I try to run the script, instead of getting it when I press the button.
Error: NameError: file line 28: name 'translate_x' is not defined
Can you please write a workable version, or place a link from the internet that shows a method using the class and calling methods using buttons? Nothing I have found from my internet search has anything like this and I'm just guessing where thigs should go.
import maya.cmds as cmds
import maya.mel as ml
class move_obj(object):
def __int__(self, *args):
self.cont = cont
self.trans = trans
def set_selected_name(self, *args):
cont = cmds.ls (selection = True)
return cont
def translate_x(self, *args):
trans = cmds.setAttr( cont[0] + '.translateX', 10)
print trans
if cmds.window ('window1', q = 1, ex = 1):
cmds.deleteUI ('window1')
cmds.window ('window1',
title = 'Translate Attr',
sizeable = 0,
resizeToFitChildren = True,
menuBar = 1)
cmds.rowLayout (numberOfColumns = 3)
cmds.button (command = translate_x,
backgroundColor = [1.0,
0.7300068665598535,
0.7300068665598535],
label = 'Translate X')
cmds.showWindow ('window1')

Can search for a record in a shapefile but how to get other fields

I can search a shapefile for an attribute and it works fine but I don't know how to get the other fields in that record once the correct records is found. Don't know if I should use SearchCursor or SelectLayerByAttribute_management.
townlands = r'F:\MyProject\Assignment\townlands.shp'
outpath = r'F:\MyProject\Assignment'
the_townland=str(text_search_townland.get())
selection = str(""" "NAME_TAG" = '""" + the_townland + "'")
selection2 = ????????????????
print selection, selection2
This code is working in that it finds the townland that the user puts in text_search_townland and it prints it as selection. I'm looking to get another field called OSM_USER from that record into selection2.
I got this working after lots of trial and error. It does need SearchCursor or at least that is how I got it working.
def new_record():
#set environment variables.
arcpy.env.workspace = r'F:\MyProject\Assignment\folklore.gdb'
myPath = r'F:\MyProject\Assignment\folklore.gdb'
editRows = arcpy.da.InsertCursor('folklore', '*')
print editRows.fields
# get the centroid of the townland from townland_centroid (fc) based on the
# townland the user enters.
database = r'F:\MyProject\Assignment\folklore.gdb'
fc = database + '/' + 'townland_centroid'
the_townland=str(text_search_townland.get())
fields = ['NAME_TAG', 'X_coord', 'Y_coord']
whereClause = '"NAME_TAG"' + " = '" + the_townland + "'"
with arcpy.da.SearchCursor(fc, fields, whereClause) as cursor:
for row in cursor:
print('{0}, {1}, {2}'.format(row[0], row[1], row[2]))
X_coord = str(row[1])
Y_coord = str(row[2])
del cursor
# Set variables with values that will populate 'folklore' featureclass.
OID = 1
ptShape = arcpy.Point(0,0)
townland = text_search_townland.get()
county = var_county2.get()
category = var_category.get()
URL = text_search_URL.get()
spec_location = "text_search_speclocation.get()"
date_entered = text_search_date_entered.get()
story_year = int(text_search_story_year.get())
X_coord_put = X_coord
Y_coord_put = Y_coord
newRecord = [OID, ptShape, townland, county, URL, spec_location, date_entered, story_year, category, X_coord, Y_coord]
editRows.insertRow(newRecord)
del editRows
Hope this helps someone.

Creating own .obj exporter for maya

I am creating my own .obj exporter for maya.
When i'm exporting just one mesh my code works just fine but when exporting several meshes / objects it fails to create the complete meshes.
I'm pretty sure that the problem is when i'm getting the
face.getVertices(), face.getUVIndex() and face.normalIndex() and printing them to the file. As i said the first mesh works fine but when it gets to the second mesh the codinates gets all wrong, they connect to the wrong triangles.
If anyone has any ideas on how to possibly loop them differently or change the values to the correct ones i would be forever greatful. Help would be very very appreciated!
Here is an example on how a multi object mesh ends out.
http://postimg.org/image/rr0fvs0v7/
import pymel.core as pm
import pymel.core.nodetypes as nt
planes = pm.ls(sl=True)
def meshFile():
def myRound(n):
return round(n, 6)
file = open("C:/Users/Blondiegirls/Desktop/test2.obj", "wb")
file.write("mtllib test2.mtl\r\n")
for p in planes[:]:
#pm.polyTriangulate(planes[0])
file.write("\r\ng default")
# Printa world kordinater
for index, point in enumerate(p.vtx):
temp = index,map(myRound, point.getPosition(space='world'))
file.write("\r\nv ")
file.write(str(' '.join(map(str, temp[1]))))
# Printa texture kordinater
mesh = pm.ls(g=True)[0]
U,V = mesh.getUVs()
UVs = zip(U,V)
for uv in UVs:
file.write("\r\nvt ")
file.write(str(uv[0])+" "+str(uv[1]))
#printa normals
for n in p.getNormals():
file.write("\r\nvn ")
file.write(str(n[0])+" "+str(n[1])+" "+str(n[2]))
file.write("\r\ns 1")
file.write("\r\ng ")
file.write(str(p))
file.write("\r\nusemtl test")
for faceIndex, face in enumerate(p.faces):
faceVertices = face.getVertices()
faceUV0 = face.getUVIndex(0)+1
faceUV1 = face.getUVIndex(1)+1
faceUV2 = face.getUVIndex(2)+1
faceNor0 = face.normalIndex(0)+1
faceNor1 = face.normalIndex(1)+1
faceNor2 = face.normalIndex(2)+1
file.write("\r\nf ")
faceVertices0 = int(faceVertices[0])+1
faceVertices1 = int(faceVertices[1])+1
faceVertices2 = int(faceVertices[2])+1
temp3 = (str(faceVertices0)) + "/" + (str(faceUV0)) +"/" + (str(faceNor0)) + " " + (str(faceVertices1)) + "/" + (str(faceUV1)) +"/" + (str(faceNor1)) + " " + (str(faceVertices2)) + "/" + (str(faceUV2)) +"/" + (str(faceNor2))
file.write(str(temp3))
file.close()
meshFile()
def MTLFile():
file2 = open("C:/Users/Blondiegirls/Desktop/test2.mtl", "wb")
object = cmds.ls(sl=1)[0].split(':')[0]
#print('object: '+object)
shipTX = pm.PyNode(object)
shadingGroups = shipTX.shadingGroups()
sg1 = shadingGroups[0]
material = sg1.listConnections(source=True, destination=False, type=nt.Lambert)[0]
file = material.color.listConnections(type=nt.File)[0]
filename = file.fileTextureName.get()
materialColor = material.getColor() #for Kd
materialAmbient = material.getAmbientColor() #for Ka
materialSpecular = material.getSpecularColor() #for Ks
refractiveIndex = material.getRefractiveIndex() #for Ni
file2.write("newmtl "+"test"+"\r\n")
file2.write("Ka "+str(materialAmbient[0])+" "+str(materialAmbient[1])+" "+str(materialAmbient[2])+"\r\n")
file2.write("Kd "+str(materialColor[0])+" "+str(materialColor[1])+" "+str(materialColor[2])+"\r\n")
file2.write("Ks "+str(materialSpecular[0])+" "+str(materialSpecular[1])+" "+str(materialSpecular[2])+"\r\n")
file2.write("d 1.0\r\n")
file2.write("Illum 2\r\n")
file2.write("map_Kd "+filename+"\r\n") #for map_Kd
file2.close()
MTLFile()
The problem is this line:
mesh = pm.ls(g=True)[0]
U,V = mesh.getUVs()
This is querying all of the geometry in the scene and returning the first object, but you should be operating on the current mesh in the iteration. I think what you want is:
U,V = p.getUVs()
Also, you should probably consider adding an argument to meshFile() rather than relying on a variable in the global scope.

python script to click button

I have this cod working for long time for a game web site but now they changed the way it should be clicked :-
def formRaid():
#print formerID
one = 1
while one == 1:
try:
global _startTime
_startTime = datetime.datetime.now()
formpage = alo("http://"+server+".outwar.com/formraid.php?target=" + bossToRaidId+"&suid="+FORMER_ID).read()
codeID = formpage.split('codeid" value="')[1].split('">')[0]
Form = alo2("http://"+server+".outwar.com/formraid.php?target=" + bossToRaidId, "target=" + bossToRaidId + "&codeid=" + codeID + "&formtime=3&submit=Launch!").read()
global RAID_ID, RAID_NAME
RAID_ID = getRaidID(Form)
RAID_NAME = getRaidName(Form)
print ""
print "***" + RAID_NAME + " Formed."
one = 0
return True
except IndexError:
print "Forming Error, retrying...."
time.sleep(1)
Now i have to click a button to go one again and the information for this button is :-
<input type="submit" value="Join this Raid!" name="submit">
How i can make the click that used in :-
formpage = alo("http://"+server+".outwar.com/formraid.php?target=" + bossToRaidId+"&suid="+FORMER_ID).read()
codeID = formpage.split('codeid" value="')[1].split('">')[0]
or the one that used in :-
Form = alo2("http://"+server+".outwar.com/formraid.php?target=" + bossToRaidId, "target=" + bossToRaidId + "&codeid=" + codeID + "&formtime=3&submit=Launch!").read()
Click that button instead of what it did before ??
opener.open("http://"+server+".outwar.com/formraid.php?target=" + bossToRaidId + "&suid="+FORMER_ID, "formtime=3&message=&bomb=none&submit=Launch!")
only works for 2.7 python

Categories