Classes interacting each other - python

i wants to make one class interact in another through a function.
a button that when clicked, add 1. But when I make the interaction, there is an error saying that Resources has not been defined
this is what i'm tring, but nothing seens to happens
from tkinter import *
class Caracteristicas:
def __init__(self,master):
self.caracteristicas = Frame(master)
self.caracteristicas.grid(row=1,column=0)
self.forca = Label(self.caracteristicas, text='FORÇA FÍSICA')
self.forca.grid(row=0,column=0)
self.show_forca = Label(self.caracteristicas,text='1')
self.show_forca.grid(row=0,column=1)
self.b_forca = Button(self.caracteristicas,text='+',command=self.ad_for)
self.b_forca.grid(row=0,column=2)
self.Forca = 1
def ad_for(self):
global Forca
self.Forca += 1
Vida = self.Forca + 10
self.show_forca['text'] = self.Forca
Recursos.show_ferimentos['text'] = Vida
class Recursos:
def __init__(self, master):
self.recursos = Frame(master)
self.recursos.grid(row=1,column=1)
self.ferimentos = Label(self.recursos, text='FERIMENTOS')
self.show_ferimentos = Label(self.recursos, text='10')
self.ferimentos.grid(row=0,column=0)
self.show_ferimentos.grid(row=1,column=0)
ficha = Tk()
a = Caracteristicas(ficha)
b = Recursos(ficha)
ficha.mainloop()
I would like to know how to make the interaction between the Characteristicsclass and theResources class
I managed to solve the previous problem however, another appeared. This is my main program, and the solution proposed does not work in this case.
from tkinter import *
from Caracteristicas import Caracteristicas
from Recursos import Recursos
ficha = Tk()
a = Caracteristicas(ficha)
b = Recursos(ficha)
ficha.mainloop()
in the case they are different documents to be used in the main

If you have instances of two classes and you need function in one of them to modify data or call methods on the other, you usually will want to pass a reference to the other object into the one that is going to interact with it.
In your code, that probably means you should pass your reference to the Recursos instance into the constructor of you Caracteristicas object, where it can be used later.
Here's a very abbreviated version of what that could look like:
class Caracteristicas:
def __init__(self, master, resource):
self.resource = resource # save value for later
... # the rest of the constructor can be the same
def ad_for(self):
self.Forca += 1
Vida = self.Forca + 10
self.show_forca['text'] = self.Forca
self.resource.show_ferimentos['text'] = Vida # main change is here!
You also need to change the code where you create your objects, to something like:
b = Recursos(ficha)
a = Caracteristicas(ficha, b) # pass the reference to the resource object in

Related

Python CLR Winforms - Passing data between .NET Winforms

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.

How to access a Class value outside of it

Sorry for such a noobish question, but, now i am writing a code that has some features i didn't know how to write by myself, so i copied them from stack overflow. I was a class i didnt study, yet i understood it mostly. The question is, how do i acess any of values created in it. Ex
class SimpleApp(object):
def __init__(self, master, filename, **kwargs):
self.master = master
self.filename = filename
self.canvrt = tk.Canvas(master, width=200, height=200, bg="#FF5733")
self.canvrt.pack()
self.update = self.draw().__next__
master.after(100, self.update)
def draw(self):
image = Image.open(self.filename)
angle = 0
while True :
tkimage = ImageTk.PhotoImage(image.rotate(angle))
canvas_obj = self.canvrt.create_image(
100, 100, image=tkimage)
self.master.after_idle(self.update)
yield
self.canvrt.delete(canvas_obj)
angle += 1
angle %= 360
how can i access the canvrt from the code? I need to acces this canvrt outisde of the class, so i can input it for example in a fucntion
You create an instance of the class SinpleApp:
myapp = SimpleApp(master, filename)
And then you can access any of its variables like this:
myapp.canvrt
However, notice that it is confusing to call filename the argument of your function clean if it expects a tkinter widget...
Depends on where you want to access it.
class NewClass():
def __init__(self,msg):
self.msg ="Hi"
def print_msg(self):
print("Message is : ", self.msg)
Inside any of the class functions/methods, you should make use of self, i.e,
self.msg
Outside of the class, use an object to access it, i.e,
obj = NewClass("hi")
obj.msg
//will print Hi

Choosing from a List of methods in a tkinter Button

Good Day,
I'm new to this forum (and quite new to programming), so I hope my question is properly formulated.
I've been trying to create a GUI in python using tkinter, and I want to have two buttons calling methods of two different classes. One method is defining an integer, the second one is reporting content. I'd have a list of objects of the latter class, and I want to choose the right instance by the integer. Here's a MWE:
import tkinter as tk
class data:
def __init__(self, content):
self.content = content
def report(self):
print("This is reported as self.content:" + str(self.content)) #This doesnt report the correct value for some reason?
print("The Class does register the correct idx:" + str(Selector.idx))
print("Using the Dict the correct value can be returned:" + str(vocables[Selector.idx].content))
class increment:
def __init__(self):
self.idx = 0
def increase(self):
self.idx += 1
print(self.idx)
vocables[self.idx].report()
root = tk.Tk()
Selector = increment()
vocables = []
for id in range(10):
vocables.append(data(id))
# print(vocables[id].content)
CheckVocable = tk.Button(root, text="Report", command=vocables[Selector.idx].report)
CheckVocable.pack()
NextVocable = tk.Button(root, text="Increase Index", command=Selector.increase)
NextVocable.pack()
root.mainloop()
I do not understand why the print of line 8 always reports the value of the first item in the list (vocabules[0] in this instance) instead of my desired value, which is returned in all other print cases. Am I messing up the work with classes or is the button behavior confusing me?
Thanks in advance!

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()

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])

Categories