Python CLR Winforms - Passing data between .NET Winforms - python

I have a fairly simple task that has eluded me when using Python to generate and automate .NET WinForms. How do I pass data between forms?
I've tried everything: using global variables, using immutable strings, etc. and nothing seems to stick. Can someone show me an example, send me a link, or let me know what I am doing wrong? I have been at this for over a week and frustration is starting to mount.
Below is a (sloppy) example of taking data from one form - a string - and sending it to another form in a Textbox.
MYSTRING = ''
import clr
clr.AddReference("System.Windows.Forms")
clr.AddReference("System.Drawing")
from System.Windows.Forms import *
from System.Drawing import *
class MyForm(Form):
def __init__(self):
self.Text1 = TextBox()
self.Button1 = Button()
self.Button1.Location = Point(0, self.Text1.Bottom + 10)
self.Button1.Text = 'Send'
self.Controls.Add(self.Text1)
self.Controls.Add(self.Button1)
self.Button1.Click += self.Button1_Click
def Button1_Click(self, sender, args):
MYSTRING = self.Text1.Text
self.TopLevel = False
f2 = MyForm2()
f2.Show()
self.TopLevel = True
class MyForm2(Form):
def __init__(self):
self.Text2 = TextBox()
self.Controls.Add(self.Text2)
self.Load += self.MyForm2_Load
def MyForm2_Load(self, sender, args):
self.Text2.Text = MYSTRING
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(MyForm())

So, I figured it out...again.
I had to set a python global variable within one of my events that triggers an event, like so...
def dgvExpanderInfo_CellDoubleClick_Event(self, sender, args):
global SelectedExpanderData_List
...
...then I could access whatever is in that globabl variable - in this case it was a list.
def MyForm2_Form_Load_Event(self, sender, args):
self.textbox1.Text = SelectedExpanderData_List[0]
self.textbox2.Text = SelectedExpanderData_List[1]
self.textbox3.Text = SelectedExpanderData_List[2]
...
I hope this helps others as I have found no real documentation on this anywhere.

Related

How to get the clock arguement of event.post(clock, data, duration) in a python device?

I cannot find an example in the Simics documentation on how the clock object is obtained so that we can use it as an argument in the post() method.
I suspect that either
an attribute can be used to get the clock or
in the ConfObject class scope we get the clock using SIM_object_clock()
I created a new module using bin\project-setup --py-device event-py
I have defined two methods in the ConfObject class scope called clock_set and clock_get.
I wanted to use these methods so that I can set/get the clock object to use in the post method.
The post() method fails when reading the device registers in the vacuum machine.
import pyobj
# Tie code to specific API, simplifying upgrade to new major version
import simics_6_api as simics
class event_py(pyobj.ConfObject):
"""This is the long-winded documentation for this Simics class.
It can be as long as you want."""
_class_desc = "one-line doc for the class"
_do_not_init = object()
def _initialize(self):
super()._initialize()
def _info(self):
return []
def _status(self):
return [("Registers", [("value", self.value.val)])]
def getter(self):
return self
# In my mind, clock_set is supposed to set the clock object. That way we can use
# it in post()
def clock_set(self):
self.clock = simics.SIM_object_clock(self)
def clock_get(self):
return self.clock(self):
class value(pyobj.SimpleAttribute(0, 'i')):
"""The <i>value</i> register."""
class ev1(pyobj.Event):
def callback(self, data):
return 'ev1 with %s' % data
class regs(pyobj.Port):
class io_memory(pyobj.Interface):
def operation(self, mop, info):
offset = (simics.SIM_get_mem_op_physical_address(mop)
+ info.start - info.base)
size = simics.SIM_get_mem_op_size(mop)
if offset == 0x00 and size == 1:
if simics.SIM_mem_op_is_read(mop):
val = self._up._up.value.val
simics.SIM_set_mem_op_value_le(mop, val)
# POST HERE AS TEST self._up._up.ev1.post(clock, val, seconds = 1)
else:
val = simics.SIM_get_mem_op_value_le(mop)
self._up._up.value.val = val
return simics.Sim_PE_No_Exception
else:
return simics.Sim_PE_IO_Error
You mention using the vacuum example machine and within its script you see that sdp->queue will point to timer. So SIM_object_clock(sdp) would return timer.
Simics is using queue attribute in all conf-objects to reference their clock individually, though other implementations are used too.
BR
Simon
#IAmIntel

Python UNO on LibreOffice Calc, rehoming a cursor

LibreOffice 5.3, python 3.53, VOID Linux
This is more of an uno question than a python question. The code below does a simple update of 3 cells. 3 buttons configured on the sheet calling dowriteonce() dowritetwice() and dowritethrice(), and they all update and work like you might expect writing numbers and text to selected cells.
Where the problem comes in, is that when a cell is edited in the UI by a user, any subsequent update of that cell by means of executing the function is blocked. So simply clicking cell C4 in the calc UI, prevents the writethrice() function from updating cell C4. If I delete the content and click another cell in the UI, say C5, then everything works normally again and C4 updates when the button is clicked.
What I would like to do is relocate the UI edit-cursor to an unused cell prior to execution in order to prevent this. User copy-paste is going to leave the active cursor in unpredictable places and that will bork calculations if I can't isolate the cursor.
So the question is, how do I move the UI edit cursor to a named cell via the UNO API, with Python? Or if it is easier, just deactivate it temporarily.
Python:
import socket
import sys
import re
import uno
import unohelper
class ODSCursor(unohelper.Base):
# predeclare class properties
ctx=None
desktop=None
model=None
activesheet=None
counter=0
scooby="Scooby"
# import namespaces
def __init__(self):
import socket
import uno
import unohelper
import sys
import re
# initialize uno handle only once and get the first sheet
#classmethod
def sheet1(cls,*args):
if cls.activesheet is not None:
return (cls.activesheet)
cls.ctx = uno.getComponentContext()
cls.desktop = cls.ctx.ServiceManager.createInstanceWithContext("com.sun.star.frame.Desktop", cls.ctx)
cls.model = cls.desktop.getCurrentComponent()
# cls.activesheet = cls.model.Sheets.getByName("Sheet1")
cls.activesheet = cls.model.Sheets.getByIndex(0)
return (cls.activesheet)
#classmethod
def writeonce(self,*args):
self.counter += 1
cell_b1 = self.activesheet.getCellRangeByName("B1")
cell_b1.String = self.counter
#classmethod
def writetwice(self,*args):
self.counter += 1
cell_b2 = self.activesheet.getCellRangeByName("B2")
cell_b2.String = self.counter
#classmethod
def writescooby(self,*args):
cell_c4 = self.activesheet.getCellRangeByName("C4")
cell_c4.String = self.scooby
### BUTTON BOUND FUNCTIONS ###
def dowriteonce(*args):
Odc = ODSCursor() # create the object
Odc.sheet1()
Odc.writeonce()
def dowritetwice(*args):
Odc = ODSCursor() # create the object
Odc.sheet1()
Odc.writetwice()
def dowritethrice(*args):
Odc = ODSCursor() # create the object
Odc.sheet1()
Odc.writescooby()
In the following code, cells are deselected before changing the values, then selected again. This way, cells can be modified even when left in edit mode by the user.
There also seems to be some confusion about Python class methods and variables, so I changed those parts as well.
import uno
import unohelper
SCOOBY = "Scooby"
class ODSCursor(unohelper.Base):
def __init__(self):
self.ctx = None
self.desktop = None
self.document = None
self.controller = None
self.sheet = None
self.counter = 0
def sheet1(self):
"""Initialize uno handle only once and get the first sheet."""
if self.sheet is not None:
return self.sheet
self.ctx = uno.getComponentContext()
self.desktop = self.ctx.ServiceManager.createInstanceWithContext(
"com.sun.star.frame.Desktop", self.ctx)
self.document = self.desktop.getCurrentComponent()
self.controller = self.document.getCurrentController()
self.sheet = self.controller.getActiveSheet()
return self.sheet
def writeonce(self):
self.writeval("B1", self.inc())
def writetwice(self):
self.writeval("B2", self.inc())
def writescooby(self):
self.writeval("C4", SCOOBY)
def writeval(self, address, value):
self.deselect()
cell = self.sheet.getCellRangeByName(address)
cell.String = value
self.controller.select(cell)
def deselect(self):
"""Select cell A1, then select nothing."""
cell_a1 = self.sheet.getCellByPosition(0, 0)
self.controller.select(cell_a1)
emptyRanges = self.document.createInstance(
"com.sun.star.sheet.SheetCellRanges")
self.controller.select(emptyRanges)
def inc(self):
"""Increment the counter and return the value."""
self.counter += 1
return self.counter
odsc = ODSCursor()
### BUTTON BOUND FUNCTIONS ###
def dowriteonce(dummy_oEvent):
odsc.sheet1()
odsc.writeonce()
def dowritetwice(dummy_oEvent):
odsc.sheet1()
odsc.writetwice()
def dowritethrice(dummy_oEvent):
odsc.sheet1()
odsc.writescooby()

blender python increment an integer

I'm pretty sure this has been answered, but I can't seem to locate it.
What I want is a python script for Blender that creates a custom tab that contains a button. When that button is pressed, it prints the value of an integer and increments it, so that when you press the button again, it shows an incremented value. Everything seems to work, except for the incremental part.
Here is the code I am using at the moment:
===
import bpy
from bpy.props import (IntProperty,)
from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup,)
def main(context):
my_number += 1
print(str(my_number))
class MySettings(PropertyGroup):
my_number = IntProperty(
name="Int property",
description="This is an integer.",
default = 1
)
class AddOne(bpy.types.Operator):
"""This is an operator"""
bl_idname = "op.add_one"
bl_label = "Increment by 1"
def execute(self, context):
main(context)
return {'FINISHED'}
class CreatePanel(bpy.types.Panel):
bl_label = "Render Setup Panel"
bl_idname = "OBJECT_PT_hello"
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'TOOLS'
bl_category = "Increment by 1 Tab"
def draw(self, context):
layout = self.layout
obj = context.object
row = layout.row()
row.operator("op.add_one")
def register():
bpy.utils.register_class(AddOne)
bpy.utils.register_class(MySettings)
bpy.utils.register_class(CreatePanel)
def unregister():
bpy.utils.unregister_class(AddOne)
bpy.utils.unregister_class(MySettings)
bpy.utils.unregister_class(CreatePanel)
if __name__ == "__main__":
register()
===
However, when I press the button 'Increment by 1', I get the following error:
"local variable 'my_number' referenced before assignment"
The point of this exercise is just to create an integer variable, store it, then increment it's value and print it out.
EDIT: I added the actual code, rather than an image of it.
The variable my_number is defined in the class MySettings - it can only be accessed through that class, whether that is inside a method that is also part of the class (self.my_number) or directly as a property that is part of an instance of the class (settings_instance.my_number).
You need to find a place outside of the operator and panel to store persistent variables. Adding a custom property to the object or scene types are common options. As you are showing your panel in the node editor, maybe you will want to add it to the material to keep it specific to a material, instead of global to the scene. You define these properties in the addons register() and remove them in unregister().
def register():
bpy.types.Scene.my_settings = bpy.props.PointerProperty(type=MySettings)
def unregister():
del bpy.types.Scene.my_settings
Then in your operator (or main() function) and your panel you can access the variable through the context paramater.
context.scene.my_settings.my_number += 1
Putting that together into your example, with a label to show the value -
import bpy
from bpy.props import (IntProperty,)
from bpy.types import (Panel, Operator, AddonPreferences, PropertyGroup,)
def main(context):
context.scene.my_settings.my_number += 1
print(str(context.scene.my_settings.my_number))
class MySettings(PropertyGroup):
my_number: IntProperty(
name="Int property",
description="This is an integer.",
default = 1
)
class AddOne(Operator):
"""This is an operator"""
bl_idname = "op.add_one"
bl_label = "Increment by 1"
def execute(self, context):
main(context)
return {'FINISHED'}
class CreatePanel(Panel):
bl_label = "Render Setup Panel"
bl_idname = "OBJECT_PT_hello"
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
bl_category = "Increment by 1 Tab"
def draw(self, context):
layout = self.layout
obj = context.object
row = layout.row()
row.operator("op.add_one")
row = layout.row()
row.label(text='Value is: '+str(context.scene.my_settings.my_number))
def register():
bpy.utils.register_class(AddOne)
bpy.utils.register_class(MySettings)
bpy.utils.register_class(CreatePanel)
bpy.types.Scene.my_settings = bpy.props.PointerProperty(type=MySettings)
def unregister():
bpy.utils.unregister_class(AddOne)
bpy.utils.unregister_class(MySettings)
bpy.utils.unregister_class(CreatePanel)
del bpy.types.Scene.my_settings
if __name__ == "__main__":
register()
You will find blender.stackexchange a better place to ask for blender specific python help.
Generally this problem "local variable 'my_number' referenced before assignment" comes when you have 'my_number' variable in code and you had not initialized that variable at top of your code or before using that variable do one thing .
Declare my_number=0 and then do your calculation on my_number variable .

Button binding in Kivy Python

I am wondering how to get my code to work. I have a class wich creates a popup window with buttons. Each button should be bound to subclass. But it doesnt work. What´s wrong with my code?
class chooser:
def __init__(self):
None
def show(self,title,options=["NOTHING"],size=(.5,.5)):
self.bts = {}
self.response = False
self.content = FloatLayout()
self.content.pos_hint = {"y":0,"x":0}
# create buttons
pos_cntr = 0
for opt in options:
self.bts[pos_cntr] = Button(text=opt)
self.bts[pos_cntr].size_hint = 1,float(1)/float(len(options))
self.bts[pos_cntr].pos_hint = {"x":0,"y":pos_cntr}
self.bts[pos_cntr].bind(on_press=self.canceldia)
self.content.add_widget(self.bts[pos_cntr])
print "bound"
pos_cntr += float(1)/float(len(options))
self.pop = Popup(title=title,content=self.content,auto_dismiss=False)
self.pop.size_hint = size
self.pop.open()
def canceldia(self,instance):
print "closing"
self.response = instance.text
self.pop.dismiss()
def getresponse(self):
return self.response
I have imported all needed modules.
I execute it so:
c = chooser()
c.show("hello","world",["welcome","close","nothing","example"])
I have create a root widget. The popup works fine and all is created nice but the buttons are not bound. Please help me!
In your loop, you always reference self.bts[pos_cntr], so you override it in every iteration. How about this?
for idx, opt in enumerate(options):
self.bts[idx] = Button(text=opt)
self.bts[idx].size_hint = 1,float(1)/float(len(options))
self.bts[idx].pos_hint = {"x":0,"y":pos_cntr}
self.bts[idx].bind(on_press=self.canceldia)
self.content.add_widget(self.bts[idx])

Masking textfield for password in Maya UI using Python

I have created a UI in Maya to send some information for rendering in a mail. For that the user has to type different data including username and password. But when typing the password, it is visible like the other texts. Is there a way where the password could appear like dots or asterisks?? The script is written in Python. Below is the image of the UI.
You could set the changeCommand of the text field to a function that would save the text to a variable and replace the text shown with an asterisk for each character.
import pymel.core as pm
class myWindow():
def __init__(self):
self.password = ''
win = pm.window(title='Test')
lo = pm.columnLayout()
self.pswdField = pm.textField(changeCommand=self.hideText)
win.show()
def hideText(self, *args):
self.password = self.pswdField.getText()
self.pswdField.setText("*" * len(self.pswdField.getText()))
That's just one way and it's not very robust..but I would definitely look into Qt like Daniel pointed out.
For my code, I tried something like this:
self.Passwd.keyPressEvent = lambda event : self.encryption()
def encryption(self):
self.a = "*"
self.Passwd.setText(self.Passwd.text() + self.a)
This is just for encoding the characters with * as you type.
You still need to capture the input into a variable or something.
And somehow segregate the keys that are not allowed in the password.
hope it gives a start.
I found the below function best suited for the above problem:
self.Passwd = QLineEdit("Password")
self.Passwd.setEchoMode(QLineEdit.Password)
If Qt is too much trouble and you don't need it 100% reliable this might suffice. It's similar to the answer from Argiri, but it replaces text as it is typed, and appends each keypress to a variable.
import pymel.core as pm
class LoginWindow():
def __init__(self):
self.password = ""
self.win = pm.window()
lo = pm.columnLayout()
self.userField = pm.textField()
self.passField = pm.textField(textChangedCommand=self.obscure)
self.goButton = pm.button("Login", c=self.go)
self.win.show()
def obscure(self, *args):
new_pw = self.passField.getText()
if len(new_pw) > len(self.password):
self.password+=new_pw[-1]
elif len(new_pw) < len(self.password):
self.password = self.password[0:-1]
self.passField.setText(u"\u2022" * len(self.password))
def go(self, *args):
print ("u: {} p: {}".format(self.userField.getText(), self.password))
pm.deleteUI(self.win)
lw = LoginWindow()
Note that if the user tried to edit the middle of the password, or tried to type it in the wrong order the reported password would be mangled. I'm not sure if that's a problem in the real world.

Categories