PyQt5 QPropertyAnimation finished() how to connect - python

In essence, i'm trying to close a window after the animation completes.
In all the documentation and examples i've looked at, they are either in:
C++
vague "method definitions"
Old style slots and connectors
how do i access the finished() that gets 'supposedly' called when the animation finishes?
self.anim = QtCore.QPropertyAnimation(window, b"windowOpacity"
self.anim.setStartValue(1)
self.anim.setEndValue(0)
self.anim.setDuration(3000)
#self.anim.finished.connect() does not exist
#QtCore.QObject.connect(stuff) is deprecated
#self.anim.finished(window.destroy) destroys window immediately
in all the examples i am reading, they use the first commented out method, but the compiler complains about 'finished' not having a 'connect()' method

every time guys...
EVERY. TIME.
i look for the answer for hours, and immediately after posting for help, i find the answer.
Commented out method #1 is correct, however you can't do a specific action in the connect() method like window.destroy or something.
correct way:`
self.anim.finished.connect(self.someMethod)
def someMethod(self):
window.destroy
what was throwing me off was; the IDE was not offering a code completion suggestion for finished.connect() (same with button.clicked.connect() actually)
this is what i get for relying too much on an IDE i suppose. hope this helps someone in the future.

Related

Call a function in a running program (and a code review)

Call a function in a running program
I am fairly new to programming and recently decided that I want to expand my Python knowledge and practice a bit. For that reason I decided that I create a little Weather Station with a Raspberry PI.
The program I am currently creating takes the output from a thermometer, parses it and writes it into a database. At the time the program is started every minute and after completing the aforementioned procedure, the program ends and all the instances get deleted (is that how you say it?).
I think that restarting it every minute wastes resources and time is getting lost so I want my program to run all the time and be accessible via command line commands (bash).
For example I have the class Thermometer:
class Thermometer():
def measure():
# do stuff
# return stuff
An instance of this class is created like this:
if __name__ == "__main__":
thermo = Thermometer
while True:
pass
Is it possible that I could call the function measure like this?:
sudo python3 < thermo.measure()
Or is there an other way to achieve this or am I doing a completely wrong approach? Also how could one describe this problem? I tried searching for "Python call function from outside" or "Python call function from bash" but I didn't find anything useful except Call a function from a running process
StackOverflow but it seems that this is the wrong Python version.
You can find my code here: github Jocomol/weatherstation
or if you don't trust the link go to github and search for "Jocomol/weatherstation".
Code review
As I already mentioned I am quite new to python and programming itself, so I make a lot of mistakes or writing useless code that could be resolved otherwise. So I am thankful for any feedback I can get on my code. If you guys could take a look at my code and point out places that aren't optimal or where I did something completely useless, I would be very happy.

Python Gtk3: "mark-set" signal of a Gtk.Textbuffer

I am trying to understand a strange behaviour of the mark-set signal emitted by a Gtk.Textbuffer in a python program.
In fact this signal is emitted (in my case) multiple times for a single user action. This sounds not logical to me and I didn't find any reference to this in the documentation.
Well, the only reference I find is an unresolved question on this website.
The question I'm talking about is this one:
Gtk3 with Python, TextView rising multiple 'mark-set' signals
I'm trying the same code than in this question and get the same result.
Does anyone has an idea about what's going wrong?
Thank you very much for any clue or piece of advice.
PS: Gtk3 is used. I've tried to run this under both Linux and OSX and got the same behavior.
change the test function to:
def test (buffer, location, mark, user_data=None):
print(mark.get_name())
so that you can see the names of the marks, most likely are marks builtin in the buffer itself by GTK

wxpython wx.AboutBox single instance

I'm still in the process of learning more about WxPython and I ran into a simple problem.
I like the wx.AboutBox class that manages how credits, licensing and other info is displayed to the user...and I'm not looking forward to building my own from scratch...although I can.
The problem here is that let's say I click on a button which brings up an AboutBox...seems like if you keep on clicking that exact button then multiple instances of the same AboutBox is brought up...and you end up multiple windows that just looks awkward in my opinion. As far as I've looked into it...there's no way to call the ShowModal() function that would allow you to get the ID of the close button in the aboutbox template and do some processing to make sure that only one instance is running.
I want to know how to stop this issue from happening...I want a single instance of wx.AboutBox and if it's not possible with this class due to it's nature/limitations then I'll have to consider building my own as a last resort.
Thanks
Creating your own AboutBox dialog is pretty easy. Here's an article that shows one way to do it: http://www.blog.pythonlibrary.org/2008/06/11/wxpython-creating-an-about-box/ or you could just use a GenericMessageDialog too. See the wxPython demo or http://www.blog.pythonlibrary.org/2010/07/10/the-dialogs-of-wxpython-part-2-of-2/
It seems like you haven't solved this problem yet. In wxPython, there's a class called "SingleInstanceChecker". I think this is what you're looking for.
http://wxpython.org/Phoenix/docs/html/SingleInstanceChecker.html

Can I put break points on background threads in Python?

I'm using the PyDev for Eclipse plugin, and I'm trying to set a break point in some code that gets run in a background thread. The break point never gets hit even though the code is executing. Here's a small example:
import thread
def go(count):
print 'count is %d.' % count # set break point here
print 'calling from main thread:'
go(13)
print 'calling from bg thread:'
thread.start_new_thread(go, (23,))
raw_input('press enter to quit.')
The break point in that example gets hit when it's called on the main thread, but not when it's called from a background thread. Is there anything I can do, or is that a limitation of the PyDev debugger?
Update
Thanks for the work arounds. I submitted a PyDev feature request, and it has been completed. It should be released with version 1.6.0. Thanks, PyDev team!
The problem is that there's no API in the thread module to know when a thread starts.
What you can do in your example is set the debugger trace function yourself (as Alex pointed) as in the code below (if you're not in the remote debugger, the pydevd.connected = True is currently required -- I'll change pydev so that this is not needed anymore). You may want to add a try..except ImportError for the pydevd import (which will fail if you're not running in the debugger)
def go(count):
import pydevd
pydevd.connected = True
pydevd.settrace(suspend=False)
print 'count is %d.' % count # set break point here
Now, on a second thought, I think that pydev can replace the start_new_thread method in the thread module providing its own function which will setup the debugger and later call the original function (just did that and it seems to be working, so, if you use the nightly that will be available in some hours, which will become the future 1.6.0, it should be working without doing anything special).
The underlying issue is with sys.settrace, the low-level Python function used to perform all tracing and debugging -- as the docs say,
The function is thread-specific; for a
debugger to support multiple threads,
it must be registered using settrace()
for each thread being debugged.
I believe that when you set a breakpoint in PyDev, the resulting settrace call is always happening on the main thread (I have not looked at PyDev recently so they may have added some way to work around that, but I don't recall any from the time when I did look).
A workaround you might implement yourself is, in your main thread after the breakpoint has been set, to use sys.gettrace to get PyDev's trace function, save it in a global variable, and make sure in all threads of interest to call sys.settrace with that global variable as the argument -- a tad cumbersome (more so for threads that already exist at the time the breakpoint is set!), but I can't think of any simpler alternative.
On this question, I found a way to start the command-line debugger:
import pdb; pdb.set_trace()
It's not as easy to use as the Eclipse debugger, but it's better than nothing.
For me this worked according to one of Fabio's posts, after setting the trace with setTrace("000.000.000.000") # where 0's are the IP of your computer running Eclipse/PyDev
threading.settrace(pydevd.GetGlobalDebugger().trace_dispatch)

Really odd (mod)_python problem

this one is hard to explain!
I am writing a python application to be ran through mod_python. At each request, the returned output differs, even though the logic is 'fixed'.
I have two classes, classA and classB. Such that:
class ClassA:
def page(self, req):
req.write("In classA page")
objB = ClassB()
objB.methodB(req)
req.write("End of page")
class ClassB:
def methodB(self, req):
req.write("In methodB")
return None
Which is a heavily snipped version of what I have. But the stuff I have snipped doesn't change the control flow. There is only one place where MethodB() is called. That is from __init__() in classA.
You would expect the following output:
In classA __init__
In methodB
End of __init__
However, seemingly randomly either get the above correct output or:
In classA __init__
In methodB
End of __init__
In methodB
The stacktrace shows that methodB is being called the second time from __init__. methodB should only be called once. If it is called a second time, you would expect that the other logic in __init__ be done twice too. But nothing before or after methodB executes and there is no recursion.
I wouldn't usually resort to using SO for my debugging, but I have been scratching my head for a while on this.
Version: 2.5.2 r252:60911
thanks in advance
Edit
Some clues that the problem might be elsewhere .... The above changes to the snippet result in the weird output 1 in every 250 or so hits. Which is odd.
The more output prior to printing "In methodB", the more it is printed subsequently incorrectly ... on average, not in direct ratio. It even does it in Lynx.
Im going back to the drawing board.
:(
In response to answer
It seems mod_python and Apache are having marital problems. A restart and things are fine for a few requests. Then it all goes increasingly pear-shaped. When issuing
/etc/rc.d/init.d/httpd stop
It takes a weirdly long amount of time. Also RAM is getting eaten up with requests. I am not that familiar with Apache's internals but it feels like (thanks to Nadia) that threads are staying alive and randomly butting in on requests. Which is plain bonkers.
Moving to mod_wsgi as S.Lott and Nadia suggested
thanks again!!
I've seen similar behaviour with mod_python before. Usually it is because apache is running multiple threads and one of them is running an older version of the code. When you refresh the page chances are the thread with the older code is serving the page. I usually fix this by stoping apache and then restarting it again
sudo /etc/init.d/apache stop
sudo /etc/init.d/apache restart
Restart on its own doesn't always work. Sometimes even that doesn't work! That might sound strange but my last resort in those rare cases where nothing is working is to add a raise Exception() statement on the first line in the handler, refresh the page, restart apache and then refresh the page again. That works every time. There must be a better solution. But that what worked for me. mod_python can drive one crazy for sure!
I hope this might help.
I don't really know, but constructors aren't supposed to return anything, so remove the return None. Even if they could return stuff, None is automatically returned if a function doesn't return anything by itself.
And I think you need a self argument in MethodB.
EDIT: Could you show more code? This is working fine.

Categories

Resources