How to import external library in QT Python? - qt

I have an issue when importing external python library in QT app.
The program is crashing when I'm trying to import the canlib.
However, no import error is caught, only application communicate appear like this:
program finished with code -1
When I comment out the canlib import, program runs fine.
import os
from pathlib import Path
import sys
import random
from Connection import Connection
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine
from PySide6.QtCore import QTimer
from canlib import kvadblib #here is an error source
if __name__ == "__main__":
app = QGuiApplication(sys.argv)
engine = QQmlApplicationEngine()
# Connection QT <---> Python
connection = Connection()
engine.rootContext().setContextProperty("connection", connection)
# End
# Hardware Init
db = kvadblib.Dbc(filename='battery_monitoring_app.dbc')
ch = communication.open_virtual_channel(1)
# End
engine.load(os.fspath(Path(__file__).resolve().parent / "qml/main.qml"))
if not engine.rootObjects():
sys.exit(-1)
### DO WHILE TRUE STUFF
def doStuff():
connection.testSignalVariable.emit(random.uniform(0.00, 2.00))
### END
timer = QTimer()
timer.timeout.connect(doStuff)
timer.start(100)
sys.exit(app.exec_())

Related

PyInstaller - AttributeError: 'ApplicationLogin' object has no attribute 'img_location'

I created a Windows .exe file from a python script using PyInstaller but when I launch the executable I get the error: AttributeError: 'ApplicationLogin' object has no attribute 'img_location'. However, running the same script from the terminal it works without issues.
Below is the piece of the code where the error is detected. The python version I used is 3.9.10
import os
from PyQt5.QtWidgets import QWidget, QDialog, QMessageBox
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QPixmap
from preventivo_config_file import Preventivo_Config
from password_edit import PasswordEdit
from gestione_utenti import UserMng
from menu_preventivo import PreventivoMenu
from preventivo_login_dialogUi import Ui_f_login_dialog
class ApplicationLogin(QDialog, Ui_f_login_dialog):
closed = pyqtSignal()
login = pyqtSignal()
def __init__(self):
super(ApplicationLogin, self).__init__()
self.read_configFile()
self.setup_login()
def read_configFile(self):
prev_config=Preventivo_Config("preventivo_config")
parametri=prev_config.preventivo_config_records()
if not parametri:
return
self.img_location=parametri['images']
self.icons_location=parametri['icons']
def setup_login(self):
self.setupUi(self)
pixmap = self.caricamento_immagini("mx1.png")
I tried to look on the web for similar issue but I didn't find any hint

I keep getting an empty task list APScheduler

I am writing a website on a Flask, I use it to run uwsgi + nginx. It was necessary to write a timer to periodically execute tasks. For this I used uwsgidecorators. The task should check the status of the scheduler tasks. To get a list of tasks, I used get_jobs(). But the list I keep getting empty.
webapp/__init__.py:
# -*- coding: utf-8 -*-
from gevent import monkey
monkey.patch_all()
import grpc.experimental.gevent
grpc.experimental.gevent.init_gevent()
from flask import Flask, session, request
from config import DevelopConfig, MqttConfig, MailConfig, ProductionConfig
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_mail import Mail
from flask_script import Manager
from flask_socketio import SocketIO
from flask_mqtt import Mqtt
from flask_login import LoginManager
from flask_babel import Babel
from flask_babel_js import BabelJS
from flask_babel import lazy_gettext as _l
from apscheduler.schedulers.gevent import GeventScheduler
app = Flask(__name__)
app.config.from_object(ProductionConfig)
app.config.from_object(MqttConfig)
app.config.from_object(MailConfig)
db = SQLAlchemy(app)
migrate = Migrate(app, db, render_as_batch=True)
mail = Mail(app)
mqtt = Mqtt(app)
manager = Manager(app, db)
login_manager = LoginManager(app)
login_manager.login_view = 'auth'
login_manager.login_message = _l("Необходимо авторизоваться для доступа к закрытой странице")
login_manager.login_message_category = "error"
scheduler = GeventScheduler()
scheduler.start()
scheduler.add_job(publish_async, args=["Hello"], id="job", trigger='interval', seconds=2)
socketio = SocketIO(app, async_mode='gevent_uwsgi') # Production Version
babel = Babel(app)
babeljs = BabelJS(app=app, view_path='/translations/')
import webapp.views
#babel.localeselector
def get_locale():
# if the user has set up the language manually it will be stored in the session,
# so we use the locale from the user settings
try:
language = session['language']
except KeyError:
language = None
if language is not None:
print(language)
return language
return request.accept_languages.best_match(app.config['LANGUAGES'].keys())
from webapp import models
def publish_async(message):
print(message)
webapp/tasks.py:
from uwsgidecorators import timer
#timer(10, target='spooler')
def check_run_tasks(args):
_list_schedulers = _scheduler_method.get_jobs()
print(_list_schedulers)
wsgi.ini:
[uwsgi]
env = PYTHONIOENCODING=UTF-8
module = wsgi:app
master = true
# processes = 5
enable-threads = true
gevent = 1024
gevent-monkey-patch = true
buffer-size=32768
# lazy-apps = true
socket = /home/sammy/projectnew/projectnew.sock
socket-timeout = 30
chmod-socket = 664
thunder-lock = true
spooler = /home/sammy/projectnew/webapp/mytasks
import = webapp/tasks.py
vacuum = true
die-on-term = true
wsgi.py:
# -*- coding: utf-8 -*-
from webapp import app, socketio
if __name__ == '__main__':
socketio.run(app, use_reloader=False)

Qt Designer Storing and Parsing User Input from Line Edit using Python to Robot Operating System (ROS)

I am currently trying to create a GUI that allows users to type in whatever words they want to be translated into R2-D2's voice.
I have used Qt 5 Designer to create a user input using Line Edit and a button that will publish the user input to a specified topic in ROS. I have also converted it into a python file using pyuic5 -o as r2d2_sound_control.py and I have a main file called main_r2d2_sound_control.py that I will run to initialise the GUI.
How do you store and parse a string from Line Edit using python? I do not know how to declare the string from the user input and parse it when the button is clicked. I'm using pyqt 4
Thank you in advance.
Link to R2-D2 voice package in GitHub https://github.com/koide3/ros2d2
Contents of r2d2_sound_control.py:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'r2d2_sound_control.ui'
#
# Created by: PyQt5 UI code generator 5.10.1
#
# WARNING! All changes made in this file will be lost!
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(505, 114)
self.pushButton_speak = QtWidgets.QPushButton(Dialog)
self.pushButton_speak.setGeometry(QtCore.QRect(300, 40, 89, 25))
self.pushButton_speak.setObjectName("pushButton_speak")
self.lineEdit_speak = QtWidgets.QLineEdit(Dialog)
self.lineEdit_speak.setGeometry(QtCore.QRect(60, 40, 201, 25))
self.lineEdit_speak.setObjectName("lineEdit_speak")
self.retranslateUi(Dialog)
self.pushButton_speak.clicked.connect(Dialog.clicked_speak)
self.lineEdit_speak.returnPressed.connect(Dialog.clicked_speak)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton_speak.setText(_translate("Dialog", "Say Out"))
Contents of main_r2d2_sound_control.py
#! /usr/bin/python3
# -*- coding: utf-8 -*-
# GUI
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
#Import the automatically generated file
from r2d2_sound_control import Ui_Dialog
# ROS
import rospy
from std_msgs.msg import String
class Test(QDialog):
def __init__(self,parent=None):
# GUI
super(Test, self).__init__(parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
# ROS pub settings
self.r2d2_sound_controller_String = String()
self.pub_r2d2_sound_controller_speak = rospy.Publisher('/ros2d2_node/speak',String,queue_size=10)
def speak_content(self):
self.input = string(lineEdit_speak)
self.lineEdit_speak.setText(self.text())
def clicked_speak(self):
"""
The slot name specified in Qt Designer.
Write the process you want to execute with the "Say Out" button.
"""
self.r2d2_sound_controller_String.data = text()
self.pub_r2d2_sound_controller_speak.publish(self.r2d2_sound_controller_String)
self.r2d2_sound_controller_String.data = ''
if __name__ == '__main__':
rospy.init_node('r2d2_sound_talker')
app = QApplication(sys.argv)
window = Test()
window.show()
sys.exit(app.exec_())
I have managed to fix it thanks to my friend. I have made the following changes to main_r2d2_sound_control.py
#! /usr/bin/python3
# -*- coding: utf-8 -*-
# GUI
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
#Import the automatically generated file
from r2d2_head_gripper_sound import Ui_Dialog
# ROS
import rospy
from std_msgs.msg import String
class Test(QDialog):
def __init__(self,parent=None):
# GUI
super(Test, self).__init__(parent)
self.ui = Ui_Dialog()
self.ui.setupUi(self)
# ROS pub settings
self.r2d2_sound_controller_String = String()
self.pub_r2d2_sound_controller_speak = rospy.Publisher('/ros2d2_node/speak',String,queue_size=10)
self.r2d2_sound_controller_String.data = ''
def clicked_speak(self):
"""
The slot name specified in Qt Designer.
Write the process you want to execute with the "Say Out" button.
"""
text = self.ui.lineEdit_speak.text()
self.r2d2_sound_controller_String.data = text
self.pub_r2d2_sound_controller_speak.publish(self.r2d2_sound_controller_String)
if __name__ == '__main__':
rospy.init_node('r2d2_head_and_gripper_talker')
app = QApplication(sys.argv)
window = Test()
window.show()
sys.exit(app.exec_())

Pyside: QNetworkAccessManager sends no Request

I tried to establish a network connection with PySide (Ubuntu 15.04, Python3.4, PySide 1.2.4). I used the example code from the documentation.
The QNetworkAccessManager does not send the request and I recieve no answer. I checked the Network state with QNetworkSession(QNetworkConfigurationManager().defaultConfiguration()).State() but it says the State is invalid. This seems to make no sense since I am on a desktop pc with a network connection via ethernet cable.
My complete example for the test is the following code:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from PySide.QtGui import QApplication
from PySide.QtCore import QUrl
from PySide.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkSession, QNetworkConfigurationManager
def replyFinished(reply):
print(reply)
if __name__ == "__main__":
app = QApplication(sys.argv)
manager = QNetworkAccessManager()
manager.finished.connect(replyFinished)
print(QNetworkSession(QNetworkConfigurationManager().defaultConfiguration()).State())
print("Sending request")
print(manager.get(QNetworkRequest(QUrl("http://www.heise.de/ct/"))))
This prints
PySide.QtNetwork.QNetworkSession.State.Invalid
Sending request
<PySide.QtNetwork.QNetworkReply object at 0x7f4b59c9af08>
but it should display the PySide.QtNetwork.QNetworkReply object twice.
My example was too small. I realized this because of the comment of Pavel Strakhov. I extended it to display a window with a button. By clicking the button it connects successfully. QNetworkSession(QNetworkConfigurationManager().defaultConfiguration()).State() is still invalid but it works.
This is the working code:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import sys
from PySide.QtGui import QApplication, QWidget, QBoxLayout, QPushButton
from PySide.QtCore import QUrl
from PySide.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkSession, QNetworkConfigurationManager
class Window(QWidget):
def __init__(self):
super().__init__()
self.manager = QNetworkAccessManager()
self.manager.finished.connect(self.reply_finished)
layout = QBoxLayout(QBoxLayout.TopToBottom)
button = QPushButton("connect")
button.clicked.connect(self.network_connect)
layout.addWidget(button)
self.setLayout(layout)
self.setWindowTitle("Network test")
self.setGeometry(100, 100, 200, 150)
self.show()
def network_connect(self):
print(QNetworkSession(QNetworkConfigurationManager().defaultConfiguration()).State())
request = QNetworkRequest(QUrl("http://example.org"))
print("Sending request")
self.manager.get(request)
def reply_finished(self, reply):
print(reply)
print(reply.readData(500))
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
app.exec_()

How to close Pyqt5 program from QML?

I started a project in Qt Creator initially with a C++ backend, but then switched it to use PyQt5. I have a main.qml, where when I press a button called Exit, I call Qt.quit().
However, I get a General Message stating: Signal QQmlEngine::quit() emitted, but no receivers connected to handle it.
My question is, how do I receive this signal and handle it?
Code:
main.py:
import sys
import PyQt5
from PyQt5 import QtCore
from PyQt5 import QtGui
from PyQt5 import QtQml
from PyQt5.QtCore import QObject pyqtSignal
class DestinyManager,(QtGui.QGuiApplication):
"""the app self"""
def __init__(self, argv):
super(DestinyManager, self).__init__(argv)
# Define a new signal called 'trigger' that has no arguments.
trigger = pyqtSignal()
def connect_and_emit_trigger(self):
# Connect the trigger signal to a slot.
self.trigger.connect(self.handle_trigger)
self.menuItem_Exit.clicked.connect(self.close)
# Emit the signal.
self.trigger.emit()
def handle_trigger(self):
# Show that the slot has been called.
print("trigger signal received")
def main(argv):
app = DestinyManager(sys.argv)
engine = QtQml.QQmlEngine(app)
component = QtQml.QQmlComponent(engine)
component.loadUrl(QtCore.QUrl("exit.qml"))
topLevel = component.create()
if topLevel is not None:
topLevel.show()
else:
for err in component.errors():
print(err.toString())
app.exec()
if __name__ == '__main__':
QObject,main(sys.argv)
Exit.qml:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
Window {
Button {
id: btn_Exit
text: "Exit"
onClicked: Qt.quit();
}
}
There are a few syntax errors in the python script, but ignoring those, the code can be made to work like this:
def main(argv):
app = DestinyManager(sys.argv)
engine = QtQml.QQmlEngine(app)
engine.quit.connect(app.quit)
...
Which is to say, you simply need to connect the qml quit signal to an appropriate slot in your python script.

Resources