Moving variables from one Qthread to another with pyqtsignal - python

I am building my first GUI in pyQT5 and I am pretty new to Python programming.
I am trying to use a set a Variable in one Qthread and using it in another. I figured that pyqtsignal was the way to do it. But i can't get it to work.
class GetCurrentSpeed(QThread):
gpsLatSig = pyqtSignal(str)
def __init__(self):
QThread.__init__(self)
def __del__(self):
self.wait()
def run(self):
while True:
####Print a value in lon and lat so that its never empty
lon = "18"
lat = "59"
###Get Current Latitude and Longitude
if report['class'] == 'TPV':
if hasattr(report, 'lat'):
lat = (str(report.lat))
self.gpsLatSig.emit(lat)
else:
lat = "59"
print("No GPS Lock")
self.gpsLatSig.emit(lat)
class PosSignals(QObject):
GetGps = GetCurrentSpeed()
def connectsig(self):
self.GetGps.gpsLatSig[str].connect(self.handle_string)
#pyqtSlot(str)
def handle_string(self, text):
print text
class OverPassApi(QThread):
GetGps = GetCurrentSpeed()
def __init__(self):
QThread.__init__(self)
self.b = PosSignals()
def __del__(self):
self.wait()
def run(self):
while True:
self.b.connectsig()
print b.handle_string()
api = overpy.Overpass()
result = api.query("""<osm-script>
<query type="way">
<around lat="%s" lon="%s" radius="30"/>
<has-kv k="name" v=""/>
</query>
<print/>
</osm-script>""" % (b.handle_string, 18))
This is just a part of the program and this might contain other errors since i have worked hard to get this to work.
My Issue is that I get the output "<main.PosSignals object at 0x72f0c210>" when i try to print the text in the handle function when i remove self like:
#pyqtSlot(str)
def handle_string(text):
print text
and when I keep self I need to provide an argument to the print b.handle_string() which then ofcourse only prints the argument I add.
What I want to achieve is to use the lat variable created in GetCurrentSpeed(QThread): and use it in class OverPassApi(QThread):

Looks like you simply forgot a self argument for handle_string.

Related

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

Python class recording attributes without specifying self ?

I have a question regarding a Python class I use in Blender. Basically, I wonder how the class works because some attributes are recorded without me specifically writing self.value = something. Here's the code:
class DialogOperator(bpy.types.Operator):
bl_idname = "object.dialog_operator"
bl_label = "Save/Load animation"
saving = bpy.props.BoolProperty(name="Save ? Else load.")
path_to_anim = bpy.props.StringProperty(name="Path to folder")
anim_name = bpy.props.StringProperty(name="Animation name:")
# path_to_anim += "/home/mehdi/Blender/Scripts/"
def execute(self, context):
# print('This is execute with: Saving: {} Name:{}'.format(self.saving, self.path_to_anim))
if self.saving:
self.launch_save()
message = 'Animation {} saved at {}'.format(self.anim_name, self.path_to_anim)
else:
self.launch_load()
message = 'Animation {} loaded'.format(self.anim_name)
self.report({'INFO'}, message)
return {'FINISHED'}
def invoke(self, context, event):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def launch_load(self):
full_path = self.path_to_anim + self.anim_name
target_armature = Humanoid(bpy.data.objects['Armature'])
load_all(full_path, target_armature, 'LastLoaded')
def launch_save(self):
full_path = self.path_to_anim + self.anim_name
source_armature = Humanoid(bpy.data.objects['Armature'])
curves = source_armature.get_curves()
save_all(curves, source_armature,full_path)
Now, how come saving, path_to_anim and anim_name are considered as attributes (I'm able to call them in execute() and launch()) even though I did not write self.saving = saving
Thanks !
This is because saving,path_to_anim and anim_name are class attributes. They are defined for the class and not for a particular instance. They are shared among the instances. Here is a link for further explanation class-instance-attributes-python

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

add 1 class to another class array

I have 2 classes:
1 which contains the data and another that contain an array
how can I create a function that add that class (like a list)
class Event(object):
def __init__(self):
self.msg_idx=0 ## the message from the panel
self.evt_id=0 ## the event id given by the server
self.Panel_Number=0 ## the panel number
self.line=""
def updateData(self,msg,event,panel,line):
self.msg_idx =msg
self.evt_id = event
self.Panel_Number = panel
self.line =line
class Events(object):
def __init__(self):
self.event =[]
def addEvent(self, Server_Event):
????????
Literally just append:
class Event(object):
def __init__(self):
self.msg_idx=0 ## the message from the panel
self.evt_id=0 ## the event id given by the server
self.Panel_Number=0 ## the panel number
self.line=""
def updateData(self,msg,event,panel,line):
self.msg_idx =msg
self.evt_id = event
self.Panel_Number = panel
self.line =line
class Events(object):
def __init__(self):
self.event =[]
def addEvent(self, Server_Event):
self.event.append(Server_Event)
something = Event()
somethings = Events()
somethings.addEvent(something)
I would question why you need such a class right now, when you could just use a list called events. But I have done something similar before and I know it makes it easier to add metadata on top.
However if you're just using it for the above without any extra analysis, it would be more efficient to just use a list.

Timed Threaded function as an attribute in a class

So I am making a text based adventure game. I am working on the engine right now and I am stuck after long hours searching for a solution for this problem.
I have a class called use_action. One of the arguments for that class is a name of a function. I would like to be able to create this action and have a possible custom function incase the item that calls this use_action does something specific.
The custom function I am working with right now is where the player is hurt and is losing 5 HP every so many seconds.
This should start when he uses a specific item and then stops when he uses the medicine that will link to the stop function. The problem I have is that the function gets called immediately. Even though I am trying to call it at the end of a long if else statement. And then when i get to where i am trying to call it it doesn't call.
I am not posting the whole class as it along with its functions are about 150 lines of code.
class use_action(object):
def __init__(self, function = None):
self.function = function
pizza_act = use_action(function = mechanics.tmr.start())
#This is located at the end of an if else statement after the player types use . . .
if self.function != None:
self.function
else:
pass
From Mechanics:
thread_list = []
class TimerClass(threading.Thread):
def __init__(self, function, time):
threading.Thread.__init__(self)
self.event = threading.Event()
self.function = function
self.time = time
thread_list.append(self)
def run(self):
while not self.event.is_set():
self.event.wait( self.time )
self.function()
def stop(self):
self.event.set()
def blank_current_readline():
# Next line said to be reasonably portable for various Unixes
(rows,cols) = struct.unpack('hh', fcntl.ioctl(sys.stdout, termios.TIOCGWINSZ,'1234'))
text_len = len(readline.get_line_buffer())+2
# ANSI escape sequences (All VT100 except ESC[0G)
sys.stdout.write('\x1b[2K') # Clear current line
sys.stdout.write('\x1b[1A\x1b[2K'*(text_len/cols)) # Move cursor up and clear line
sys.stdout.write('\x1b[0G') # Move to start of line
def pizza_poisoned_action():
# threading.Timer(10, pizza_poisoned_action).start()
blank_current_readline()
print "You lost 5 hp."
initialization.gamer.hp -= 5
sys.stdout.write('> ' + readline.get_line_buffer())
sys.stdout.flush() # Needed or text doesn't show until a key is pressed
tmr = TimerClass(pizza_poisoned_action, 5)
Sorry about the length, I tried to only post the relevant stuff for this. If you think i should post some other piece of code that may be relevant let me know!
If you want to pass a function, don't call it. Or else, you'll be passing the return value.
pizza_act = use_action(function = mechanics.test()) #Wrong!
pizza_act = use_action(function = mechanics.test) #Right

Categories