I am trying to write a basic program using leap motion, I just want to constantly run the on_frame method but the method only runs once and disconnecting the device does not call the on_disconnect method. The program will not run until I hit enter, What am I doing wrong? Thanks for the help :
import Leap, sys, thread
from Leap import CircleGesture, KeyTapGesture, ScreenTapGesture,SwipeGesture
class LeapMotionListener(Leap.Listener):
state_names = ["STATE_INVAILD","STATE_START","STATE_UPDATE", "STATE_END"]
def on_init(self, controller):
print "Initialized"
def on_connect(self, controller):
print "Connected"
controller.enable_gesture(Leap.Gesture.TYPE_CIRCLE);
controller.enable_gesture(Leap.Gesture.TYPE_KEY_TAP);
controller.enable_gesture(Leap.Gesture.TYPE_SCREEN_TAP);
controller.enable_gesture(Leap.Gesture.TYPE_SWIPE);
print "All gestures enabled"
def on_disconnect(self, controller):
print "Disconnected"
def on_exit(self, controller):
print "Exit"
def on_frame(self, controller):
frame= controller.frame()
print "\n Frame ID"+ str(frame.id)
print "num of hands: " +str(len(frame.hands))
print "num of gestures: " +str(len(frame.gestures()))
for gesture in frame.gestures():
if gesture.type is Leap.Gesture.TYPE_CIRCLE:
circle = Leap.CircleGesture(gesture)
elif gesture.type is Leap.Gesture.TYPE_SWIPE:
swipe = Leap.SwipeGesture(gesture)
elif gesture.type is Leap.Gesture.TYPE_KEY_TAP:
key_tap = Leap.KeyTapGesture(gesture)
elif gesture.type is Leap.Gesture.TYPE_SCREEN_TAP:
screen_tap = Leap.ScreenTapGesture(gesture)
def main():
listener= LeapMotionListener()
controller = Leap.Controller()
controller.add_listener(listener)
print "Press enter to quit: "
try:
sys.stdin.readline()
except KeyboardInterrupt:
pass
finally:
controller.remove_listener(listener)
if __name__ == "__main__":
main()
Your code runs fine from the command line. I.e:
> python scriptname.py
Are you running from Idle? if so, this part:
try:
sys.stdin.readline()
except KeyboardInterrupt:
pass
doesn't work. (See Python 3.2 Idle vs terminal) A similar issue might exist in other IDEs.
The following should work in Idle, but you have to use Ctrl-C to exit.
# Keep this process running until a Ctrl-C is pressed
print "Press Ctrl-C to quit..."
try:
while True:
time.sleep(1)
except:
print "Quiting"
finally:
# Remove the sample listener when done
controller.remove_listener(listener)
Quitting on any key stroke in both Idle and the command line seemed surprisingly difficult and complex when I tried it some time ago -- but then, I'm a Python duffer.
Related
I ran into a problem with my telegram-bot program. when I launch it, after a couple seconds this error shows up. is it related to my internet connection ? or the code is wrong ?
the code:
from telegram.ext import *
def start_command(update, context):
update.massage.reply_text("Hi. I'm a test bot")
def help_command(update, context):
update.massage.reply_text("if you need help! search on Google")
def main():
app = Application.builder().token('your token').build()
app.add_handler(CommandHandler("start", start_command))
app.add_handler(CommandHandler("help", help_command))
app.run_polling()
app.idle()
if __name__ == '__main__':
main()
the error:
File "C:\Users\AppData\Local\Programs\Python\Python311\Lib\site-packages\telegram\request\_httpxrequest.py", line 200, in do_request
raise TimedOut from err
telegram.error.TimedOut: Timed out
Try this:
def main():
app = Application.builder().token('your token').read_timeout(30).write_timeout(30).build()
app.add_handler(CommandHandler("start", start_command))
app.add_handler(CommandHandler("help", help_command))
app.run_polling()
app.idle()
if __name__ == '__main__':
main()
Im very new to python and I've been trying to make a simple macro that clicks a button whenever it sees it. It works perfectly when I run it manually on Visual studio code but closes immediately when I execute the file with python3.10.
import pyautogui
import time
time.sleep(5)
waitingloop = 1
while waitingloop == 1:
if pyautogui.locateCenterOnScreen("notif.png") == None:
time.sleep(0.5)
else:
pyautogui.click("notif.png")
time.sleep(0.5)
pyautogui.click(x=1751, y=792)
time.sleep(1)
pyautogui.click(x=1909, y=875, clicks=5, interval= 2)
time.sleep(0.5)
pyautogui.click(x=1751, y=792)
time.sleep(5)
pyautogui.click(x=956, y=344)
time.sleep(1)
pyautogui.keyDown("alt")
time.sleep(0.25)
pyautogui.press("tab")
time.sleep(0.25)
pyautogui.keyUp("alt")
pyautogui.click("chat.png")
break
How do I make a loop that only starts running after the expected input?
I am currently following this tutorial on threading in PyQt (code from here). As it was written in PyQt4 (and Python2), I adapted the code to work with PyQt5 and Python3.
Here is the gui file (newdesign.py):
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'threading_design.ui'
#
# Created by: PyQt5 UI code generator 5.6
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(526, 373)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.subreddits_input_layout = QtWidgets.QHBoxLayout()
self.subreddits_input_layout.setObjectName("subreddits_input_layout")
self.label_subreddits = QtWidgets.QLabel(self.centralwidget)
self.label_subreddits.setObjectName("label_subreddits")
self.subreddits_input_layout.addWidget(self.label_subreddits)
self.edit_subreddits = QtWidgets.QLineEdit(self.centralwidget)
self.edit_subreddits.setObjectName("edit_subreddits")
self.subreddits_input_layout.addWidget(self.edit_subreddits)
self.verticalLayout.addLayout(self.subreddits_input_layout)
self.label_submissions_list = QtWidgets.QLabel(self.centralwidget)
self.label_submissions_list.setObjectName("label_submissions_list")
self.verticalLayout.addWidget(self.label_submissions_list)
self.list_submissions = QtWidgets.QListWidget(self.centralwidget)
self.list_submissions.setBatchSize(1)
self.list_submissions.setObjectName("list_submissions")
self.verticalLayout.addWidget(self.list_submissions)
self.progress_bar = QtWidgets.QProgressBar(self.centralwidget)
self.progress_bar.setProperty("value", 0)
self.progress_bar.setObjectName("progress_bar")
self.verticalLayout.addWidget(self.progress_bar)
self.buttons_layout = QtWidgets.QHBoxLayout()
self.buttons_layout.setObjectName("buttons_layout")
self.btn_stop = QtWidgets.QPushButton(self.centralwidget)
self.btn_stop.setEnabled(False)
self.btn_stop.setObjectName("btn_stop")
self.buttons_layout.addWidget(self.btn_stop)
self.btn_start = QtWidgets.QPushButton(self.centralwidget)
self.btn_start.setObjectName("btn_start")
self.buttons_layout.addWidget(self.btn_start)
self.verticalLayout.addLayout(self.buttons_layout)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Threading Tutorial - nikolak.com "))
self.label_subreddits.setText(_translate("MainWindow", "Subreddits:"))
self.edit_subreddits.setPlaceholderText(_translate("MainWindow", "python,programming,linux,etc (comma separated)"))
self.label_submissions_list.setText(_translate("MainWindow", "Submissions:"))
self.btn_stop.setText(_translate("MainWindow", "Stop"))
self.btn_start.setText(_translate("MainWindow", "Start"))
and the main script (main.py):
from PyQt5 import QtWidgets
from PyQt5.QtCore import QThread, pyqtSignal, QObject
import sys
import newdesign
import urllib.request
import json
import time
class getPostsThread(QThread):
def __init__(self, subreddits):
"""
Make a new thread instance with the specified
subreddits as the first argument. The subreddits argument
will be stored in an instance variable called subreddits
which then can be accessed by all other class instance functions
:param subreddits: A list of subreddit names
:type subreddits: list
"""
QThread.__init__(self)
self.subreddits = subreddits
def __del__(self):
self.wait()
def _get_top_post(self, subreddit):
"""
Return a pre-formatted string with top post title, author,
and subreddit name from the subreddit passed as the only required
argument.
:param subreddit: A valid subreddit name
:type subreddit: str
:return: A string with top post title, author,
and subreddit name from that subreddit.
:rtype: str
"""
url = "https://www.reddit.com/r/{}.json?limit=1".format(subreddit)
headers = {'User-Agent': 'nikolak#outlook.com tutorial code'}
request = urllib.request.Request(url, header=headers)
response = urllib.request.urlopen(request)
data = json.load(response)
top_post = data['data']['children'][0]['data']
return "'{title}' by {author} in {subreddit}".format(**top_post)
def run(self):
"""
Go over every item in the self.subreddits list
(which was supplied during __init__)
and for every item assume it's a string with valid subreddit
name and fetch the top post using the _get_top_post method
from reddit. Store the result in a local variable named
top_post and then emit a pyqtSignal add_post(QString) where
QString is equal to the top_post variable that was set by the
_get_top_post function.
"""
for subreddit in self.subreddits:
top_post = self._get_top_post(subreddit)
self.emit(pyqtSignal('add_post(QString)'), top_post)
self.sleep(2)
class ThreadingTutorial(QtWidgets.QMainWindow, newdesign.Ui_MainWindow):
"""
How the basic structure of PyQt GUI code looks and behaves like is
explained in this tutorial
http://nikolak.com/pyqt-qt-designer-getting-started/
"""
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.btn_start.clicked.connect(self.start_getting_top_posts)
def start_getting_top_posts(self):
# Get the subreddits user entered into an QLineEdit field
# this will be equal to '' if there is no text entered
subreddit_list = str(self.edit_subreddits.text()).split(',')
if subreddit_list == ['']: # since ''.split(',') == [''] we use that to check
# whether there is anything there to fetch from
# and if not show a message and abort
QtWidgets.QMessageBox.critical(self, "No subreddits",
"You didn't enter any subreddits.",
QtWidgets.QMessageBox.Ok)
return
# Set the maximum value of progress bar, can be any int and it will
# be automatically converted to x/100% values
# e.g. max_value = 3, current_value = 1, the progress bar will show 33%
self.progress_bar.setMaximum(len(subreddit_list))
# Setting the value on every run to 0
self.progress_bar.setValue(0)
# We have a list of subreddits which we use to create a new getPostsThread
# instance and we pass that list to the thread
self.get_thread = getPostsThread(subreddit_list)
# Next we need to connect the events from that thread to functions we want
# to be run when those pyqtSignals get fired
# Adding post will be handeled in the add_post method and the pyqtSignal that
# the thread will emit is pyqtSignal("add_post(QString)")
# the rest is same as we can use to connect any pyqtSignal
self.connect(self.get_thread, pyqtSignal("add_post(QString)"), self.add_post)
# This is pretty self explanatory
# regardless of whether the thread finishes or the user terminates it
# we want to show the notification to the user that adding is done
# and regardless of whether it was terminated or finished by itself
# the finished pyqtSignal will go off. So we don't need to catch the
# terminated one specifically, but we could if we wanted.
self.connect(self.get_thread, pyqtSignal("finished()"), self.done)
# We have all the events we need connected we can start the thread
self.get_thread.start()
# At this point we want to allow user to stop/terminate the thread
# so we enable that button
self.btn_stop.setEnabled(True)
# And we connect the click of that button to the built in
# terminate method that all QThread instances have
self.btn_stop.clicked.connect(self.get_thread.terminate)
# We don't want to enable user to start another thread while this one is
# running so we disable the start button.
self.btn_start.setEnabled(False)
def add_post(self, post_text):
"""
Add the text that's given to this function to the
list_submissions QListWidget we have in our GUI and
increase the current value of progress bar by 1
:param post_text: text of the item to add to the list
:type post_text: str
"""
self.list_submissions.addItem(post_text)
self.progress_bar.setValue(self.progress_bar.value()+1)
def done(self):
"""
Show the message that fetching posts is done.
Disable Stop button, enable the Start one and reset progress bar to 0
"""
self.btn_stop.setEnabled(False)
self.btn_start.setEnabled(True)
self.progress_bar.setValue(0)
QtWidgets.QMessageBox.information(self, "Done!", "Done fetching posts!")
def main():
app = QtWidgets.QApplication(sys.argv)
form = ThreadingTutorial()
form.show()
app.exec_()
if __name__ == '__main__':
main()
Now I'm getting the following error:
AttributeError: 'ThreadingTutorial' object has no attribute 'connect'
Can anyone please tell me how to fix this? Any help would be, as always, very much appreciated.
Using QObject.connect() and similar in PyQt4 is known as "Old style signals", and is not supported in PyQt5 anymore, it supports only "New style signals", which already in PyQt4 was the recommended way to connect signals.
In PyQt5 you need to use the connect() and emit() methods of the bound signal directly, e.g. instead of:
self.emit(pyqtSignal('add_post(QString)'), top_post)
...
self.connect(self.get_thread, pyqtSignal("add_post(QString)"), self.add_post)
self.connect(self.get_thread, pyqtSignal("finished()"), self.done)
use:
self.add_post.emit(top_post)
...
self.get_thread.add_post.connect(self.add_post)
self.get_thread.finished.connect(self.done)
However for this to work you need to explicitly define the add_post signal on your getPostsThread first, otherwise you'll get an attribute error.
class getPostsThread(QThread):
add_post = pyqtSignal(str)
...
In PyQt4 with old style signals when a signal was used it was automatically defined, this now needs to be done explicitly.
I'm writing an application that use Pybind11 to embed Python interpreter (Windows, 64 bit, Visual C++ 2017). From Python, I need to spawn multiple processes, but it seems doesn't works. I try the following code as test:
import multiprocessing
import os
import sys
import time
print("This is the name of the script: ", sys.argv[0])
print("Number of arguments: ", len(sys.argv))
print("The arguments are: " , str(sys.argv))
prefix=str(os.getpid())+"-"
if len(sys.argv) > 1:
__name__ = "__mp_main__"
def print_cube(num):
"""
function to print cube of given num
"""
print("Cube: {}".format(num * num * num))
def print_square(num):
"""
function to print square of given num
"""
print("Square: {}".format(num * num))
print(__name__)
if __name__ == "__main__":
print(prefix, "checkpoint 1")
# creating processes
p1 = multiprocessing.Process(target=print_square, args=(10, ))
p1.daemon = True
p2 = multiprocessing.Process(target=print_cube, args=(10, ))
# starting process 1
p1.start()
print(prefix, "checkpoint 2")
# starting process 2
p2.start()
print(prefix, "checkpoint 3")
# wait until process 1 is finished
print(prefix, "checkpoint 4")
p1.join()
print(prefix, "checkpoint 5")
# wait until process 2 is finished
p2.join()
print(prefix, "checkpoint 6")
# both processes finished
print("Done!")
print(prefix, "checkpoint 7")
time.sleep(10)
Running it with the Python from command prompt, I obtain:
This is the name of the script: mp.py
Number of arguments: 1
The arguments are: ['mp.py']
__main__
12872- checkpoint 1
12872- checkpoint 2
This is the name of the script: C:\tmp\mp.py
Number of arguments: 1
The arguments are: ['C:\\tmp\\mp.py']
__mp_main__
7744- checkpoint 7
Square: 100
12872- checkpoint 3
12872- checkpoint 4
12872- checkpoint 5
This is the name of the script: C:\tmp\mp.py
Number of arguments: 1
The arguments are: ['C:\\tmp\\mp.py']
__mp_main__
15020- checkpoint 7
Cube: 1000
12872- checkpoint 6
Done!
12872- checkpoint 7
which is correct. If I try the same from a C++ project with Pybind11, the output is:
This is the name of the script: C:\AGPX\Documenti\TestPyBind\x64\Debug\TestPyBind.exe
Number of arguments: 1
The arguments are: ['C:\\AGPX\\Documenti\\TestPyBind\\x64\\Debug\\TestPyBind.exe']
__main__
4440- checkpoint 1
This is the name of the script: C:\AGPX\Documenti\TestPyBind\x64\Debug\TestPyBind.exe
Number of arguments: 4
The arguments are: ['C:\\AGPX\\Documenti\\TestPyBind\\x64\\Debug\\TestPyBind.exe', '-c', 'from multiprocessing.spawn import spawn_main; spawn_main(parent_pid=4440, pipe_handle=128)', '--multiprocessing-fork']
__mp_main__
10176- checkpoint 7
Note that, in this case, the variable __name__ is always set to '__main__', so I have to change it manually (for the spawned processes) to '__mp_main__' (I can detect the child processes thanks to the sys.argv). This is the first strange behaviour.
The parent process have pid 4440 and I can see the process in process explorer.
The first child process have pid 10176 and it reach the end 'checkpoint 7' and process disappears from process explorer. However, the main process doesn't print 'checkpoint 2', that is looks like it hangs on 'p1.start()' and I cannot understand why.
The complete C++ code is:
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/embed.h>
#include <iostream>
namespace py = pybind11;
using namespace py::literals;
int wmain(int argc, wchar_t **argv)
{
py::initialize_interpreter();
PySys_SetArgv(argc, argv);
std::string pyCode = std::string(R"(
import multiprocessing
import os
import sys
import time
print("This is the name of the script: ", sys.argv[0])
print("Number of arguments: ", len(sys.argv))
print("The arguments are: " , str(sys.argv))
prefix=str(os.getpid())+"-"
if len(sys.argv) > 1:
__name__ = "__mp_main__"
def print_cube(num):
"""
function to print cube of given num
"""
print("Cube: {}".format(num * num * num))
def print_square(num):
"""
function to print square of given num
"""
print("Square: {}".format(num * num))
print(__name__)
if __name__ == "__main__":
print(prefix, "checkpoint 1")
# creating processes
p1 = multiprocessing.Process(target=print_square, args=(10, ))
p1.daemon = True
p2 = multiprocessing.Process(target=print_cube, args=(10, ))
# starting process 1
p1.start()
print(prefix, "checkpoint 2")
# starting process 2
p2.start()
print(prefix, "checkpoint 3")
# wait until process 1 is finished
print(prefix, "checkpoint 4")
p1.join()
print(prefix, "checkpoint 5")
# wait until process 2 is finished
p2.join()
print(prefix, "checkpoint 6")
# both processes finished
print("Done!")
print(prefix, "checkpoint 7")
time.sleep(10)
)");
try
{
py::exec(pyCode);
} catch (const std::exception &e) {
std::cout << e.what();
}
py::finalize_interpreter();
}
Can anyone explain to me how to overcome this problem, please?
Thanks in advance (and I apologize for my english).
Ok, thanks to this link: https://blender.stackexchange.com/questions/8530/how-to-get-python-multiprocessing-module-working-on-windows, I solved this strange issue (that seems to be Windows related).
It's not a Pybind11 issue, but a Python C API itself.
You can solve the issue by setting sys.executable equals to the path of the python interpreter executable (python.exe) and by writing the python code to a file and setting the path to the __file__ variable. That is, I have to add:
import sys
sys.executable = "C:\\Users\\MyUserName\\Miniconda3\\python.exe"
__file__ = "C:\\tmp\\run.py"
and I need to write the python code to the file specified by __file__, that is:
FILE *f = nullptr;
fopen_s(&f, "c:\\tmp\\run.py", "wt");
fprintf(f, "%s", pyCode.c_str());
fclose(f);
just before execute py::exec(pyCode).
In addition the code:
if len(sys.argv) > 1:
__name__ = "__mp_main__"
is no longer necessary. However, note that in this way the runned processes are not embedded anymore and, unfortunately, if you want to directly pass a C++ module to them, you cannot do it.
Hope this can help someone else.
In main.py
returnCode = self.rouDialogForm.exec_()
if returnCode == QtWidgets.QDialog.Accepted:
print(float(self.rouDialogForm.ui.leStartMhz.text()))
if returnCode ==QtWidgets.QDialog.Rejected:
print(float(self.rouDialogForm.ui.leStopMhz.text()))
In rouDialog.py
def setupUi(self, Dialog):
#GUI CODE
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.butConnect.clicked.connect(self.acceptDialog)
def acceptDialog(self):
self.accept()
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
#Label set texts are here
import myResources_rc
I can catch the Rejected signal that is generated after clicking the window closing icon and print out the required text from the line edit.
But when I press the button that will generate accept signal(but connect) program just crashes run time.
I tried different syntax and different imports to make it work.
attempt #1: in rouDialog.py instead of self.accept()
self.done(QtWidgets.QDialog.Accepted)
another attempt: in rouDialog.py instead of self.accept()
super(Ui_Dialog,self).accept()
another one:
QtWidgets.QDialog.accept(self)
SOLVED:
Adding this to my rouDialog.py solved all my problems.Hope it will help someone else in future.
self.butReadout.clicked.connect(Dialog.accept)
#QtCore.pyqtSlot()
def accept(self):
pass
Edit: I can't mark my answer as correct , since i need to wait 2 days.