IBM Watson with pyqt5 window is freezing in the while loop - python

My window freezing in the while loop how can i fix it or how to wait for input into loop if i add input("") something program is not freezing anymore but i doesnt want use console.
from ibm_watson import AssistantV2
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
import sys
from PyQt5 import QtWidgets
class Pencere(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.gr=0
self.say=0
self.yazi_alani=QtWidgets.QLineEdit()
self.send=QtWidgets.QPushButton("Send")
self.cevap=QtWidgets.QLabel("")
v_box=QtWidgets.QVBoxLayout()
h_box=QtWidgets.QHBoxLayout()
h_box.addStretch()
v_box.addWidget(self.cevap)
v_box.addStretch()
v_box.addWidget(self.yazi_alani)
v_box.addWidget(self.send)
h_box.addLayout(v_box)
self.setLayout(h_box)
self.send.clicked.connect(self.gonder)
self.setGeometry(200,200,500,500)
self.show()
self.watson()
def watson(self):
while self.say==0:
self.say+=1
# Set up Assistant service.
authenticator = IAMAuthenticator('4CpKAKUsLRpYvcUX_nQRR1MGnYM1WqJLUhE4XS-p4B7Y') # replace with API key
service = AssistantV2(
version = '2020-04-01',
authenticator = authenticator
)
service.set_service_url('https://api.eu-gb.assistant.watson.cloud.ibm.com/instances/49abc832-b899-4359-aca3-ea100ceb777a')
assistant_id = '8e3469cd-deaa-465f-8f6d-e1e4cbf7d9c1' # replace with assistant ID
# Create session.
session_id = service.create_session(
assistant_id = assistant_id
).get_result()['session_id']
# Initialize with emptyhi values to start the conversation.
message_input = {'text': ''}
current_action = ''
while current_action != 'end_conversation':
# Clear any action flag set by the previous response.
current_action = ''
# Send message to assistant.
response = service.message(
assistant_id,
session_id,
input = message_input
).get_result()
# Print the output from dialog, if any. Supports only a single
# text response.
if response['output']['generic']:
if response['output']['generic'][0]['response_type'] == 'text':
self.cevap.setText(response['output']['generic'][0]['text'])
# Check for client actions requested by the assistant.
if 'actions' in response['output']:
if response['output']['actions'][0]['type'] == 'client':
current_action = response['output']['actions'][0]['name']
# If we're not done, prompt for next round of input.
if current_action != 'end_conversation':
user_input=self.yazi_alani.text()
message_input = {
'text': user_input
}
# We're done, so we delete the session.
service.delete_session(
assistant_id = assistant_id,
session_id = session_id
)
def gonder(self):
return self.yazi_alani.text()
app=QtWidgets.QApplication(sys.argv)
pencere=Pencere()
sys.exit(app.exec_())
In this code i use input window is not frozing anymore i doesnt want use console
how can i fix this or something
if current_action != 'end_conversation':
input("->")
user_input=self.yazi_alani.text()
message_input = {
'text': user_input
}

You don't have to run time consuming tasks since they freeze the GUI, if a task is very time consuming then you should run it in another thread and send the result to the GUI thread using signals as shown in the following example:
import threading
import sys
from ibm_watson import AssistantV2
from ibm_cloud_sdk_core.authenticators import IAMAuthenticator
from PyQt5 import QtCore, QtWidgets
class IBMWatsonManager(QtCore.QObject):
connected = QtCore.pyqtSignal()
disconnected = QtCore.pyqtSignal()
messageChanged = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super().__init__(parent)
self._assistant_id = "8e3469cd-deaa-465f-8f6d-e1e4cbf7d9c1"
self._session_id = ""
self._service = None
self.connected.connect(self.send_message)
self._is_active = False
#property
def assistant_id(self):
return self._assistant_id
#property
def session_id(self):
return self._session_id
#property
def service(self):
return self._service
#property
def is_active(self):
return self._is_active
def create_session(self):
threading.Thread(target=self._create_session, daemon=True).start()
def _create_session(self):
authenticator = IAMAuthenticator(
"4CpKAKUsLRpYvcUX_nQRR1MGnYM1WqJLUhE4XS-p4B7Y"
) # replace with API key
self._service = AssistantV2(version="2020-04-01", authenticator=authenticator)
self.service.set_service_url(
"https://api.eu-gb.assistant.watson.cloud.ibm.com/instances/49abc832-b899-4359-aca3-ea100ceb777a"
)
self._session_id = self.service.create_session(
assistant_id=self.assistant_id
).get_result()["session_id"]
self._is_active = True
self.connected.emit()
#QtCore.pyqtSlot()
#QtCore.pyqtSlot(str)
def send_message(self, text=""):
threading.Thread(target=self._send_message, args=(text,), daemon=True).start()
def _send_message(self, text):
response = self.service.message(
self.assistant_id, self.session_id, input={"text": text}
).get_result()
generic = response["output"]["generic"]
if generic:
t = "\n".join([g["text"] for g in generic if g["response_type"] == "text"])
self.messageChanged.emit(t)
output = response["output"]
if "actions" in output:
client_response = output["actions"][0]
if client_response["type"] == "client":
current_action = client_response["name"]
if current_action == "end_conversation":
self._close_session()
self._is_active = False
self.disconnected.emit()
def _close_session(self):
self.service.delete_session(
assistant_id=self.assistant_id, session_id=self.session_id
)
class Widget(QtWidgets.QWidget):
sendSignal = QtCore.pyqtSignal(str)
def __init__(self):
super().__init__()
self.init_ui()
def init_ui(self):
self.message_le = QtWidgets.QLineEdit()
self.send_button = QtWidgets.QPushButton("Send")
self.message_lbl = QtWidgets.QLabel()
v_box = QtWidgets.QVBoxLayout()
v_box.addWidget(self.message_lbl)
v_box.addStretch()
v_box.addWidget(self.message_le)
v_box.addWidget(self.send_button)
h_box = QtWidgets.QHBoxLayout(self)
h_box.addStretch()
h_box.addLayout(v_box)
self.disable()
self.setGeometry(200, 200, 500, 500)
self.send_button.clicked.connect(self.on_clicked)
#QtCore.pyqtSlot()
def enable(self):
self.message_le.setEnabled(True)
self.send_button.setEnabled(True)
#QtCore.pyqtSlot()
def disable(self):
self.message_le.setEnabled(False)
self.send_button.setEnabled(False)
#QtCore.pyqtSlot()
def on_clicked(self):
text = self.message_le.text()
self.sendSignal.emit(text)
self.message_le.clear()
#QtCore.pyqtSlot(str)
def set_message(self, text):
self.message_lbl.setText(text)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
manager = IBMWatsonManager()
manager.connected.connect(w.enable)
manager.disconnected.connect(w.disable)
w.sendSignal.connect(manager.send_message)
manager.messageChanged.connect(w.set_message)
manager.create_session()
sys.exit(app.exec_())

Related

In PyQt5's QListWidget, how can I only show the tooltip for an item when the user chooses it?

I was inspired by this repo to add custom tooltip text to items when they are added to the QListWidget. However, I only want the tooltip message to appear when the item is chosen. How would I implement this?
Here is a GUI example that I have to test this feature:
import serial, time, sys
import serial.tools.list_ports
from PyQt5 import QtGui, QtWidgets, QtCore
import json, time
class GUI(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.__init_ui()
def closeEvent(self, event):
super().closeEvent(event)
def __init_ui(self):
self.setWindowTitle('QListWidgetToolTipDemo')
self.history_log = HistoryList()
self.history_log.itemDoubleClicked.connect(self.history_item_selected)
self.history_log.returnPressed.connect(self.history_item_selected)
self.history_log.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.line_edit = QtWidgets.QLineEdit()
self.line_edit.returnPressed.connect(self.populate_history)
self.middle_layout = QtWidgets.QHBoxLayout()
self.middle_layout.addWidget(self.history_log)
self.middle_layout.addWidget(self.line_edit)
middle_layout_wrapper = QtWidgets.QWidget()
middle_layout_wrapper.setLayout(self.middle_layout)
middle_layout_wrapper.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
# Sets full GUI layout
gui_layout = QtWidgets.QVBoxLayout()
gui_layout.addWidget(middle_layout_wrapper)
gui_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
gui_layout.setContentsMargins(QtCore.QMargins(0, 0, 0, 0))
self.setLayout(gui_layout)
def populate_history(self):
self.history_log.addItem(self.line_edit.text())
self.line_edit.clear()
def history_item_selected(self):
self.line_edit.setText(self.history_log.currentItem().text())
class HistoryList(QtWidgets.QListWidget):
returnPressed = QtCore.pyqtSignal()
def __init__(self) -> None:
super().__init__()
self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.setMouseTracking(True)
self.itemEntered.connect(self.__showToolTip)
def keyPressEvent(self, ev):
super().keyPressEvent(ev)
if ev.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
self.returnPressed.emit()
def addItem(self, aitem) -> None:
item = ''
text = ''
if isinstance(aitem, str):
item = QtWidgets.QListWidgetItem()
text = aitem
item.setText(text)
elif isinstance(aitem, QtWidgets.QListWidgetItem):
item = aitem
text = item.text()
self.setItemWidget(item, QtWidgets.QWidget())
super().addItem(item)
def __showToolTip(self, item: QtWidgets.QListWidgetItem):
text = item.text()
text_width = self.fontMetrics().boundingRect(text).width()
width = self.width()
info = {"time":str(time.time()), "entry":text}
info = json.dumps(info, indent=4)
item.setToolTip(info)
if __name__ == "__main__":
app = QtWidgets.QApplication([])
console = GUI()
screensize = app.desktop().availableGeometry().size()
console.show()
exit(app.exec_())
Currently, the following is how a tooltip works for any item:
Example where only display tooltip when item is selected:
Expanding on the suggestion from musicamante in the comments, I was able to get tooltip to display only for the selected item by overriding the event method and watch for a tooltip event (inspired from this SO post)
import serial, time, sys
import serial.tools.list_ports
from PyQt5 import QtGui, QtWidgets, QtCore
import json, time
class GUI(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.__init_ui()
def closeEvent(self, event):
super().closeEvent(event)
def __init_ui(self):
self.setWindowTitle('QListWidgetToolTipDemo')
self.history_log = HistoryList()
self.history_log.itemDoubleClicked.connect(self.history_item_selected)
self.history_log.returnPressed.connect(self.history_item_selected)
self.history_log.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.line_edit = QtWidgets.QLineEdit()
self.line_edit.returnPressed.connect(self.populate_history)
self.middle_layout = QtWidgets.QHBoxLayout()
self.middle_layout.addWidget(self.history_log)
self.middle_layout.addWidget(self.line_edit)
middle_layout_wrapper = QtWidgets.QWidget()
middle_layout_wrapper.setLayout(self.middle_layout)
middle_layout_wrapper.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed)
# Sets full GUI layout
gui_layout = QtWidgets.QVBoxLayout()
gui_layout.addWidget(middle_layout_wrapper)
gui_layout.setAlignment(QtCore.Qt.AlignmentFlag.AlignTop)
gui_layout.setContentsMargins(QtCore.QMargins(0, 0, 0, 0))
self.setLayout(gui_layout)
def populate_history(self):
self.history_log.addItem(self.line_edit.text())
self.line_edit.clear()
def history_item_selected(self):
self.line_edit.setText(self.history_log.currentItem().text())
class HistoryList(QtWidgets.QListWidget):
returnPressed = QtCore.pyqtSignal()
def __init__(self) -> None:
super().__init__()
self.setSelectionMode(QtWidgets.QAbstractItemView.SingleSelection)
self.setMouseTracking(True)
self.itemEntered.connect(self.__addToolTip)
self.items_tooltip_info_dict = dict()
def keyPressEvent(self, ev):
super().keyPressEvent(ev)
if ev.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
self.returnPressed.emit()
def event(self, e: QtCore.QEvent) -> bool:
if e.type() == QtCore.QEvent.ToolTip:
if not self.selectedItems():
QtWidgets.QToolTip.hideText()
return True
else:
index = self.indexFromItem(self.currentItem()).row()
info = json.dumps(self.items_tooltip_info_dict[index], indent=4)
QtWidgets.QToolTip.showText(e.globalPos(),info)
e.accept()
return super().event(e)
def addItem(self, aitem) -> None:
item = ''
text = ''
if isinstance(aitem, str):
item = QtWidgets.QListWidgetItem()
text = aitem
item.setText(text)
elif isinstance(aitem, QtWidgets.QListWidgetItem):
item = aitem
text = item.text()
self.setItemWidget(item, QtWidgets.QWidget())
super().addItem(item)
def __addToolTip(self, item: QtWidgets.QListWidgetItem):
text = item.text()
info = {"time":str(time.time()), "entry":text}
index = self.indexFromItem(item).row()
self.items_tooltip_info_dict[index] = info
if __name__ == "__main__":
app = QtWidgets.QApplication([])
console = GUI()
screensize = app.desktop().availableGeometry().size()
console.show()
exit(app.exec_())

How can I return my session variable to my main code with PyQt5?

I don't know how to express my problem in a question because I am a very PyQt5 learner and I don't know the vocabularies, but come on.
I need to return the session_user variable (in the login () function) to my main code. This variable needs to be passed to the main screen after the login is completed, but I don't know of a function in PyQt5 that returns a variable that is not of type int like: accept (), reject (), done ().
Is it possible to return my session_user variable to my main code with some PyQt5 function like the ones I mentioned?
my code:
from PyQt5 import uic, QtWidgets
from PyQt5.QtWidgets import QDialog
from views.ui.login.telaLogin import Ui_Dialog
import sys
from control.exception_login import verification_login_user
class ViewLogin(QDialog):
def __init__(self):
super().__init__()
self.viewlogin = Ui_Dialog()
self.viewlogin.setupUi(self)
self.viewlogin.button_login.clicked.connect(self.login)
def login(self):
self.login = self.viewlogin.login_login.text()
self.password = self.viewlogin.login_password.text()
erro = verification_login_user(self.login, self.password)
if (erro == False):
self.close()
session_user = (self.login, self.senha)
#self.done(r) # I understand its functionality # PROBLEM
#return (session_user) # PROBLEM
self.accept() # The problem would end here if I didn't need the variable sessao_user
elif(erro == True):
self.viewlogin.login_login.setText('')
self.viewlogin.login_password.setText('')
app = QtWidgets.QApplication([])
w = ViewLogin()
result = w.exec_()
print(result) # desired result = (' login', 'password')
# real result = 1
sys.exit(app.exec_())
One of the approaches you could implement is via threading module.
Create a class Controller and Daemon to True (this ensures the thread will be killed after the app closes).
class Controller(threading.Thread):
def __init__(self):
super(Controller, self).__init__(daemon = True)
self.my_variable = 0
self.variables_from_gui = None
Overwrite the run method:
def run(self):
print("My main loop is here!")
while True:
print("Button presses: {}, Variables from gui: {}".format(self.button_presses, self.variables_from_gui))
time.sleep(1) #This wont freeze the gui
Add a function that will register the button login click:
def login(self, variables_from_gui = None):
#Do you login stuff
self.variables_from_gui = variables_from_gui
self.button_presses += 1
In the App class (in your case that would be the main GUI class) from the login function start a new thread and pass variables to it.
def login(self):
#Stuff to do in your GUI
variables_to_send = 0, "Text", {"key" : 10}
threading.Thread(target = lambda: self.controller.login(variables_from_gui = variables_to_send)).start()
Also in your GUI class create a Controller object and start it:
self.controller = Controller()
self.controller.start() #Start the run method in the Controller()
There are plenty of things that can be done better and make it more Threading safe. But that is outside of this question topic.
Whole code:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
import threading
import time
class App(QWidget):
def __init__(self):
super().__init__()
self.left = 10
self.top = 10
self.width = 320
self.height = 200
self.initUI()
def initUI(self):
self.controller = Controller()
self.controller.start() #Start the run method in the Controller()
self.setGeometry(self.left, self.top, self.width, self.height)
button = QPushButton("My login", self)
button.move(100,70)
button.clicked.connect(self.login)
self.show()
def login(self):
#Stuff to do in your GUI
variables_to_send = 0, "Text", {"key" : 10}
threading.Thread(target = lambda: self.controller.login(variables_from_gui = variables_to_send)).start()
class Controller(threading.Thread):
def __init__(self):
super(Controller, self).__init__(daemon = True)
self.button_presses = 0
self.variables_from_gui = None
def run(self):
print("My main loop is here!")
while True:
print("Button presses: {}, Variables from gui: {}".format(self.button_presses, self.variables_from_gui))
time.sleep(1) #This wont freeze the gui
def login(self, variables_from_gui = None):
#Do you login stuff
self.variables_from_gui = variables_from_gui
self.button_presses += 1
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())

pyqt5 in not responding state when calling the url

i just implemented a login in pyqt but in between the calling the url and getting the response the qt window is showing the not responding state
can anyone please suggest me how to avoid not responding state
code:
class Login(QDialog):
def __init__(self, height, width, parent=None):
super(Login, self).__init__(parent)
self.resize(300, 300)
size = self.geometry()
self.move((width-size.width())/2, (height-size.height())/2)
username = QLabel("Username", self)
username.move(100, 35)
self.textName = QLineEdit(self)
password = QLabel("Password", self)
password.move(100, 110)
self.textPass = QLineEdit(self)
self.textPass.setEchoMode(QLineEdit.Password)
self.buttonLogin = QPushButton('Login', self)
self.buttonLogin.clicked.connect(self.handleLogin)
layout = QVBoxLayout(self)
layout.addWidget(self.textName)
layout.addWidget(self.textPass)
layout.addWidget(self.buttonLogin)
def handleLogin(self):
# TODO: Connect to flask application to check login credentials
payload = {"username":self.textName.text(),"password":self.textPass.text()}
print("payload:", payload)
r = requests.post("http://127.0.0.1:5000/login",data=payload)
print(r.content.decode("utf-8"))
if r.status_code == 200:
self.accept()
else:
QMessageBox.warning(self, 'Error', 'Bad user or password')
1. Use threads: Tasks that consume a lot of time must be executed in another thread
import requests
from PyQt5 import QtCore, QtWidgets
class LoginWorker(QtCore.QObject):
logged = QtCore.pyqtSignal(bool)
def setCredentials(self, username, password):
self.payload = {"username": username, "password": password}
#QtCore.pyqtSlot()
def login(self):
print("payload:", self.payload)
r = requests.post("http://127.0.0.1:5000/login",data=self.payload)
print(r.content.decode("utf-8"))
status = r.status_code == 200
self.logged.emit(status)
class Login(QtWidgets.QDialog):
def __init__(self, height, width, parent=None):
super(Login, self).__init__(parent)
self.resize(300, 300)
size = self.geometry()
self.move((width-size.width())/2, (height-size.height())/2)
username = QtWidgets.QLabel("Username")
self.textName = QtWidgets.QLineEdit()
password = QtWidgets.QLabel("Password")
self.textPass = QtWidgets.QLineEdit()
self.textPass.setEchoMode(QtWidgets.QLineEdit.Password)
self.buttonLogin = QtWidgets.QPushButton('Login')
self.buttonLogin.clicked.connect(self.handleLogin)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(username, alignment=QtCore.Qt.AlignCenter)
layout.addWidget(self.textName)
layout.addWidget(password, alignment=QtCore.Qt.AlignCenter)
layout.addWidget(self.textPass)
layout.addWidget(self.buttonLogin)
layout.addStretch()
thread = QtCore.QThread(self)
thread.start()
self.login_worker = LoginWorker()
self.login_worker.moveToThread(thread)
self.login_worker.logged.connect(self.onLogged)
def handleLogin(self):
# TODO: Connect to flask application to check login credentials
self.login_worker.setCredentials(self.textName.text(), self.textPass.text())
QtCore.QTimer.singleShot(0, self.login_worker.login)
def onLogged(self, status):
if status:
self.accept()
else:
QtWidgets.QMessageBox.warning(self, 'Error', 'Bad user or password')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Login(100, 100)
w.show()
sys.exit(app.exec_())
2. Use QNAM:
from PyQt5 import QtCore, QtWidgets, QtNetwork
class Login(QtWidgets.QDialog):
def __init__(self, height, width, parent=None):
super(Login, self).__init__(parent)
self.resize(300, 300)
size = self.geometry()
self.move((width-size.width())/2, (height-size.height())/2)
username = QtWidgets.QLabel("Username")
self.textName = QtWidgets.QLineEdit()
password = QtWidgets.QLabel("Password")
self.textPass = QtWidgets.QLineEdit()
self.textPass.setEchoMode(QtWidgets.QLineEdit.Password)
self.buttonLogin = QtWidgets.QPushButton('Login')
self.buttonLogin.clicked.connect(self.handleLogin)
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(username, alignment=QtCore.Qt.AlignCenter)
layout.addWidget(self.textName)
layout.addWidget(password, alignment=QtCore.Qt.AlignCenter)
layout.addWidget(self.textPass)
layout.addWidget(self.buttonLogin)
layout.addStretch()
def handleLogin(self):
# TODO: Connect to flask application to check login credentials
postData = QtCore.QUrlQuery()
postData.addQueryItem("username", self.textName.text())
postData.addQueryItem("password", self.textPass.text())
qnam = QtNetwork.QNetworkAccessManager()
url = "http://127.0.0.1:5000/home"
reply = qnam.post(QtNetwork.QNetworkRequest(QtCore.QUrl(url)), postData.toString(QtCore.QUrl.FullyEncoded).encode())
loop = QtCore.QEventLoop()
reply.finished.connect(loop.quit)
loop.exec_()
code = reply.attribute(QtNetwork.QNetworkRequest.HttpStatusCodeAttribute)
if code == 200:
self.accept()
else:
QtWidgets.QMessageBox.warning(self, 'Error', 'Bad user or password')
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Login(100, 100)
w.show()
sys.exit(app.exec_())

location permission popup

I'm making a web browser in PyQt5 and Python. How to make location permission popup like the following:
Here is my code:
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtWebEngineWidgets import *
from PyQt5 import QtCore, QtGui, QtWidgets, QtWebEngineWidgets,QtWebEngine
from PyQt5.QtPrintSupport import *
import os
import sys
from time import sleep
from threading import Timer
import re
import urllib.request
class SearchPanel(QtWidgets.QWidget):
searched = QtCore.pyqtSignal(str, QtWebEngineWidgets.QWebEnginePage.FindFlag)
closed = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(SearchPanel, self).__init__(parent)
lay = QtWidgets.QHBoxLayout(self)
self.case_button = QtWidgets.QPushButton('Match &Case', checkable=True)
next_button = QtWidgets.QPushButton('&Next')
prev_button = QtWidgets.QPushButton('&Previous')
self.search_le = QtWidgets.QLineEdit()
self.setFocusProxy(self.search_le)
next_button.clicked.connect(self.update_searching)
prev_button.clicked.connect(self.on_preview_find)
self.case_button.clicked.connect(self.update_searching)
for btn in (self.case_button, self.search_le, next_button, prev_button, ):
lay.addWidget(btn)
if isinstance(btn, QtWidgets.QPushButton): btn.clicked.connect(self.setFocus)
self.search_le.textChanged.connect(self.update_searching)
self.search_le.returnPressed.connect(self.update_searching)
self.closed.connect(self.search_le.clear)
QtWidgets.QShortcut(QtGui.QKeySequence.FindNext, self, activated=next_button.animateClick)
QtWidgets.QShortcut(QtGui.QKeySequence.FindPrevious, self, activated=prev_button.animateClick)
QtWidgets.QShortcut(QtGui.QKeySequence(QtCore.Qt.Key_Escape), self.search_le, activated=self.closed)
#QtCore.pyqtSlot()
def on_preview_find(self):
self.update_searching(QtWebEngineWidgets.QWebEnginePage.FindBackward)
#QtCore.pyqtSlot()
def update_searching(self, direction=QtWebEngineWidgets.QWebEnginePage.FindFlag()):
flag = direction
if self.case_button.isChecked():
flag |= QtWebEngineWidgets.QWebEnginePage.FindCaseSensitively
self.searched.emit(self.search_le.text(), flag)
def showEvent(self, event):
super(SearchPanel, self).showEvent(event)
self.setFocus(True)
class AboutDialog(QDialog):
def __init__(self, *args, **kwargs):
super(AboutDialog, self).__init__(*args, **kwargs)
QBtn = QDialogButtonBox.Ok # No cancel
self.buttonBox = QDialogButtonBox(QBtn)
self.buttonBox.accepted.connect(self.accept)
self.buttonBox.rejected.connect(self.reject)
layout = QVBoxLayout()
title = QLabel("Pyxis Browser")
font = title.font()
font.setPointSize(20)
title.setFont(font)
layout.addWidget(title)
logo = QLabel()
logo.setPixmap(QPixmap(os.path.join('', 'ma-icon-128.png')))
layout.addWidget(logo)
layout.addWidget(QLabel("Version 1.0.0"))
layout.addWidget(QLabel("Copyright."))
for i in range(0, layout.count()):
layout.itemAt(i).setAlignment(Qt.AlignHCenter)
layout.addWidget(self.buttonBox)
self.setLayout(layout)
class MyPage(QWebEnginePage):
def __init__(self, *args, **kwargs):
super(MyPage, self).__init__(*args, **kwargs)
def triggerAction(self, action, checked=False):
if action == QWebEnginePage.OpenLinkInNewWindow:
self.createWindow(QWebEnginePage.WebBrowserWindow)
return super(MyPage, self).triggerAction(action, checked)
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.browser = QWebEngineView()
self.browser.setUrl(QUrl("https://androidd.pw/Login/"))
QWebEnginePage.JavascriptCanOpenWindows:True
self.browser.urlChanged.connect(self.update_urlbar)
self.browser.urlChanged.connect(self.page_loading)
self.browser.loadFinished.connect(self.update_title)
self.setCentralWidget(self.browser)
self.status = QStatusBar()
self.setStatusBar(self.status)
self.setCentralWidget(self.browser)
#self.browser.page().settings().setAttribute(QWebEngineSettings.AllowGeolocationOnInsecureOrigins, True)
navtb = QToolBar("Navigation")
navtb.setIconSize(QSize(16, 16))
self.addToolBar(navtb)
guide = QToolBar("Navigation")
guide.setIconSize(QSize(16, 16))
self.addToolBar(guide)
self.guidestate = QLabel() # Yes, really!
self.guidestate.setText('Welcome to Pyxis Ad')
font = self.guidestate.font()
font.setPointSize(14)
self.guidestate.setFont(font)
guide.addWidget(self.guidestate)
self.done_btn = QAction(QIcon(os.path.join('', 'done.png')), "Done", self)
self.done_btn.setVisible(False)
self.done_btn.triggered.connect(self.start_earning)
guide.addAction(self.done_btn)
self.child_domain = QAction(QIcon(os.path.join('', 'new_ad.png')), "Load New Pyxis Domain", self)
self.child_domain.setVisible(False)
self.child_domain.triggered.connect(self.load_child_domain)
guide.addAction(self.child_domain)
self.advertise = QAction(QIcon(os.path.join('', 'new_ad.png')), "Load New Avertisements Site", self)
self.advertise.setVisible(False)
self.advertise.triggered.connect(self.load_advertise)
guide.addAction(self.advertise)
self.load_new_url = QAction(QIcon(os.path.join('', 'new_ad.png')), "Reload New Site", self)
self.load_new_url.setVisible(False)
self.load_new_url.triggered.connect(self.new_ad_site)
guide.addAction(self.load_new_url)
back_btn = QAction(QIcon(os.path.join('', 'arrow-180.png')), "Back", self)
back_btn.setStatusTip("Back to previous page")
back_btn.triggered.connect(self.browser.back)
navtb.addAction(back_btn)
next_btn = QAction(QIcon(os.path.join('', 'arrow-000.png')), "Forward", self)
next_btn.setStatusTip("Forward to next page")
next_btn.triggered.connect(self.browser.forward)
navtb.addAction(next_btn)
reload_btn = QAction(QIcon(os.path.join('', 'arrow-circle-315.png')), "Reload", self)
reload_btn.setStatusTip("Reload page")
reload_btn.triggered.connect(self.browser.reload)
navtb.addAction(reload_btn)
home_btn = QAction(QIcon(os.path.join('', 'home.png')), "Home", self)
home_btn.setStatusTip("Go home")
home_btn.triggered.connect(self.navigate_home)
navtb.addAction(home_btn)
navtb.addSeparator()
self.httpsicon = QLabel() # Yes, really!
self.httpsicon.setPixmap(QPixmap(os.path.join('', 'lock-nossl.png')))
navtb.addWidget(self.httpsicon)
self.urlbar = QLineEdit()
#self.urlbar.setDisabled(1)
self.urlbar.returnPressed.connect(self.navigate_to_url)
navtb.addWidget(self.urlbar)
QWebEnginePage.JavascriptCanOpenWindows:True
stop_btn = QAction(QIcon(os.path.join('', 'cross-circle.png')), "Stop", self)
stop_btn.setStatusTip("Stop loading current page")
stop_btn.triggered.connect(self.browser.stop)
navtb.addAction(stop_btn)
help_menu = self.menuBar().addMenu("&Help")
about_action = QAction(QIcon(os.path.join('', 'question.png')), "About Browser", self)
about_action.setStatusTip("Find out more about Pyxis Browser") # Hungry!
about_action.triggered.connect(self.about)
help_menu.addAction(about_action)
navigate_mozarella_action = QAction(QIcon(os.path.join('', 'lifebuoy.png')), "Pyxis Homepage", self)
navigate_mozarella_action.setStatusTip("Go to Browser Homepage")
navigate_mozarella_action.triggered.connect(self.navigate_mozarella)
help_menu.addAction(navigate_mozarella_action)
self.setWindowIcon(QIcon(os.path.join('', 'ma-icon-64.png')))
def update_title(self):
title = self.browser.page().title()
self.setWindowTitle("%s - Pyxis" % title)
def page_loading(self):
title = 'Loading...'
self.setWindowTitle("%s - Pyxis" % title)
def navigate_mozarella(self):
self.browser.setUrl(QUrl("http://androidd.pw"))
def about(self):
dlg = AboutDialog()
dlg.exec_()
def print_page(self):
dlg = QPrintPreviewDialog()
dlg.paintRequested.connect(self.browser.print_)
dlg.exec_()
def navigate_home(self):
self.browser.setUrl(QUrl("http://androidd.pw"))
def start_earning(self):
self.browser.setUrl(QUrl("http://androidd.pw/API/legal_click"))
def load_child_domain(self):
self.browser.setUrl(QUrl('https://androidd.pw/API/getRandom/general'))
def load_advertise(self):
self.browser.setUrl(QUrl('https://androidd.pw/API/getRandom/ads'))
def navigate_to_url(self): # Does not receive the Url
q = QUrl(self.urlbar.text())
if q.scheme() == "":
q.setScheme("http")
self.browser.setUrl(q)
def timeout(self):
self.guidestate.setText('Ad Completed')
self.done_btn.setVisible(True)
self.load_new_url.setVisible(False)
def new_ad_site(self):
with urllib.request.urlopen("http://androidd.pw/API/single_site") as single_url:single = single_url.read()
self.browser.setUrl(QUrl(single.decode('utf-8')))
def update_urlbar(self, q):
###################################################################################
url = q.host()
#http://ipackersmovers.com/API/url/general?url=http://www.firsttecnology.us
with urllib.request.urlopen("http://androidd.pw/API/url/general?url="+url) as pyxis_url:pyxis = pyxis_url.read()
with urllib.request.urlopen("http://androidd.pw/API/url/ads?url="+url) as dom_url:ad = dom_url.read()
#with urllib.request.urlopen("http://androidd.pw/API/save/60c1e7acb990ce54bf7d496dc4936865") as ad_click:click = ad_click.read()
if pyxis == b'0':
pyxis = False
else:
pyxis = True
if ad == b'0':
ad = False
else:
ad = True
if pyxis:
self.guidestate.setText('Welcome to Pyxis Ad | You are currently on working area')
self.done_btn.setVisible(False)
self.load_new_url.setVisible(False)
self.child_domain.setVisible(False)
self.advertise.setVisible(False)
elif ad:
self.guidestate.setText('Click On Adsense Ad | if Ads are not visible then Reload new site =>')
self.done_btn.setVisible(False)
self.load_new_url.setVisible(True)
self.child_domain.setVisible(False)
self.advertise.setVisible(False)
elif q.host() == 'www.google.com' or q.host() == 'google.com':
query_url = q.query()
if re.search("^q=.*&gws_rd=ssl$", query_url):
highlighting = query_url[2:-11]
else:
highlighting = query_url[2:]
with urllib.request.urlopen("http://androidd.pw/API/url/general?url="+highlighting) as pyxis_url:pyxis_child = pyxis_url.read()
with urllib.request.urlopen("http://androidd.pw/API/url/ads?url="+highlighting) as dom_url:advert = dom_url.read()
self.guidestate.setText('Please Click on the first link from search results | Reload For New =>')
if pyxis_child.decode('utf-8'):
self.child_domain.setVisible(True)
elif advert.decode('utf-8'):
self.advertise.setVisible(True)
self.done_btn.setVisible(False)
self.load_new_url.setVisible(False)
direction=QtWebEngineWidgets.QWebEnginePage.FindFlag()
self.browser.findText(highlighting, direction)
else:
self.guidestate.setText('Please wait...')
self.done_btn.setVisible(False)
self.load_new_url.setVisible(False)
self.child_domain.setVisible(False)
self.advertise.setVisible(False)
# duration is in seconds
t = Timer(25, self.timeout)
t.start()
############################Checking which site is on###############################
if q.scheme() == 'https':
# Secure padlock icon
self.httpsicon.setPixmap(QPixmap(os.path.join('images', 'lock-ssl.png')))
else:
# Insecure padlock icon
self.httpsicon.setPixmap(QPixmap(os.path.join('images', 'lock-nossl.png')))
self.urlbar.setText(q.toString())
self.urlbar.setCursorPosition(0)
def createWindow(self, windowType):
if windowType == QWebEnginePage.WebBrowserTab:
self.browser = MainWindow()
self.browser.setAttribute(Qt.WA_DeleteOnClose, True)
self.browser.show()
return self.browser
return super(MainWindow, self).createWindow(windowType)
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setApplicationName("Pyxis")
app.setOrganizationName("Pyxis")
app.setOrganizationDomain("Pyxis")
window = MainWindow()
window.show()
app.exec_()
You have to use the featurePermissionRequested signal that will be issued every time the browser requires permissions to use some resource, then open a dialog and if the user accepts or not then use setFeaturePermission() to accept or deny the feature:
from PyQt5 import QtCore, QtWidgets, QtWebEngineWidgets
class WebEnginePage(QtWebEngineWidgets.QWebEnginePage):
def __init__(self, parent=None):
super(WebEnginePage, self).__init__(parent)
self.featurePermissionRequested.connect(self.handleFeaturePermissionRequested)
#QtCore.pyqtSlot(QtCore.QUrl, QtWebEngineWidgets.QWebEnginePage.Feature)
def handleFeaturePermissionRequested(self, securityOrigin, feature):
title = "Permission Request"
questionForFeature = {
QtWebEngineWidgets.QWebEnginePage.Geolocation : "Allow {feature} to access your location information?",
QtWebEngineWidgets.QWebEnginePage.MediaAudioCapture : "Allow {feature} to access your microphone?",
QtWebEngineWidgets.QWebEnginePage.MediaVideoCapture : "Allow {feature} to access your webcam?",
QtWebEngineWidgets.QWebEnginePage.MediaAudioVideoCapture : "Allow {feature} to lock your mouse cursor?",
QtWebEngineWidgets.QWebEnginePage.DesktopVideoCapture : "Allow {feature} to capture video of your desktop?",
QtWebEngineWidgets.QWebEnginePage.DesktopAudioVideoCapture: "Allow {feature} to capture audio and video of your desktop?"
}
question = questionForFeature.get(feature)
if question:
question = question.format(feature=securityOrigin.host())
if QtWidgets.QMessageBox.question(self.view().window(), title, question) == QtWidgets.QMessageBox.Yes:
self.setFeaturePermission(securityOrigin, feature, QtWebEngineWidgets.QWebEnginePage.PermissionGrantedByUser)
else:
self.setFeaturePermission(securityOrigin, feature, QtWebEngineWidgets.QWebEnginePage.PermissionDeniedByUser)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.browser = QtWebEngineWidgets.QWebEngineView()
page = WebEnginePage(self.browser)
self.browser.setPage(page)
self.browser.load(QtCore.QUrl("https://developers.google.com/maps/documentation/javascript/examples/map-geolocation"))
self.setCentralWidget(self.browser)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.showMaximized()
sys.exit(app.exec())

Pyqt GUI suddenly not responding after clicked button 2 twice using QThread

i try create QThread class for my process, when i clicked Generate button it's don't show anything in my QTextEdit, when i click the button again my GUI suddenly not responding.
My Code
Updated Code
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import ipaddress
class Stream(QObject):
newText = pyqtSignal(str)
def write(self, text):
self.newText.emit(str(text))
def flush(self):
pass
class MyClass(object):
def __init__(self, device_type=None, ip=None, username=None, password=None, secret=None, command=None):
self.device_type = device_type
self.ip = ip
self.username = username
self.password = password
self.secret = secret
self.command = command
class sshConnection(QThread):
def __init__(self):
QThread.__init__(self)
def __del__(self):
self.wait()
def runSSH(self):
#doo process
print('Haii')
for x in range(100):
print(x)
class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent=parent)
self.device_list = [] # object array
self.setWindowTitle("Network Automation")
self.setFixedSize(350,500)
############################# Input IP
sys.stdout = Stream(newText=self.onUpdateText)
# Device Type
lb_device_list = QLabel(self)
lb_device_list.setText('Device Type')
self.cb_device_list = QComboBox(self)
self.cb_device_list.addItem('cisco_ios')
self.cb_device_list.addItem('cisco_s300')
# Ip Device
lb_ip = QLabel(self)
lb_ip.setText('IP Address')
self.le_ip = QLineEdit(self)
self.le_ip.setText('')
self.le_ip.setPlaceholderText('Input Device IP')
self.le_ip.setFixedWidth(150)
# username
lb_username = QLabel(self)
self.le_username = QLineEdit(self)
lb_username.setText('Username')
self.le_username.setText('')
self.le_username.setPlaceholderText('Input Username')
self.le_username.setFixedWidth(150)
# password
lb_password = QLabel(self)
self.le_password = QLineEdit(self)
lb_password.setText('Password')
self.le_password.setText('')
self.le_password.setPlaceholderText('Input Password')
self.le_password.setFixedWidth(150)
# Privilage Password
lb_enable = QLabel(self)
lb_enable.setText('Privilege Mode Password')
self.le_enable = QLineEdit(self)
self.le_enable.setText('')
self.le_enable.setPlaceholderText('Input Enable Password')
self.le_enable.setFixedWidth(150)
# button generate and add
btgenerate = QPushButton(self)
btgenerate.setText('Generate')
btgenerate.setFixedWidth(70)
btadd = QPushButton(self)
btadd.setText('Add')
# button delete
btdel = QPushButton(self)
btdel.setFixedWidth(70)
btdel.setText('Remove')
# line
line = QFrame(self)
line.setFrameShape(QFrame.VLine)
line.setFrameShadow(QFrame.Sunken)
line.setLineWidth(3)
#line 2
line2 = QFrame(self)
line2.setFrameShape(QFrame.HLine)
line2.setFrameShadow(QFrame.Sunken)
line2.setLineWidth(3)
########################### Layout Ip Device List
lb3 = QLabel(self)
lb3.setText('IP Device List')
self.ip_device_list = QListWidget(self)
self.ip_device_list.setFixedWidth(150)
# self.combobox_ip_list = QComboBox(self)
# self.combobox_ip_list.setFixedWidth(170)
############################## SubLayout and Layout
hblayout = QHBoxLayout()
hblayout.addWidget(btgenerate)
hblayout.addWidget(btadd)
############################### Processs
processlabel = QLabel("Process",self)
self.process = QTextEdit(self)
self.process.setLineWrapColumnOrWidth(400)
self.process.setLineWrapMode(QTextEdit.FixedPixelWidth)
self.process.setReadOnly(True)
sublayout = QVBoxLayout()
sublayout.addWidget(lb_device_list)
sublayout.addWidget(self.cb_device_list)
sublayout.addWidget(lb_ip)
sublayout.addWidget(self.le_ip)
sublayout.addWidget(lb_username)
sublayout.addWidget(self.le_username)
sublayout.addWidget(lb_password)
sublayout.addWidget(self.le_password)
sublayout.addWidget(lb_enable)
sublayout.addWidget(self.le_enable)
sublayout.addLayout(hblayout)
sublayout2 = QVBoxLayout()
sublayout2.addWidget(lb3)
sublayout2.addWidget(self.ip_device_list)
#sublayout2.addWidget(self.combobox_ip_list)
sublayout2.addWidget(btdel)
sublayout2.addStretch(1)
sublayout3 = QVBoxLayout()
sublayout3.addWidget(processlabel)
sublayout3.addWidget(self.process)
layout = QGridLayout(self)
layout.addLayout(sublayout, 0, 0)
layout.addWidget(line, 0, 1)
layout.addWidget(line2, 1, 0, 1, 3)
#layout.addWidget(processlabel,2,0)
layout.addLayout(sublayout3,2,0,2,3)
layout.addLayout(sublayout2, 0, 2)
btadd.clicked.connect(self.addDevice)
btdel.clicked.connect(self.remove)
btgenerate.clicked.connect(self.runThread)
def onUpdateText(self, text):
cursor = self.process.textCursor()
cursor.movePosition(QTextCursor.End)
cursor.insertText(text)
self.process.setTextCursor(cursor)
self.process.ensureCursorVisible()
# ----------- AddDevice Process
def addDevice(self):
try:
ip = self.le_ip.text()
ipaddress.ip_address(ip)
device_type = str(self.cb_device_list.currentText())
username = self.le_username.text()
password = self.le_password.text()
secret = self.le_enable.text()
command = 'show tech'
coomand2 = ''
self.device_list.append(MyClass(device_type, ip, username, password, secret, command))
# self.combobox_ip_list.addItem(ip)# Add Ip to ComboBox
self.ip_device_list.addItem(ip)
self.le_ip.clear()
self.le_username.clear()
self.le_password.clear()
self.le_enable.clear()
for list in self.device_list:
print(list.ip, list.device_type)
except ValueError:
print("insert you're ip correctly")
QMessageBox.question(self, 'Warning', "Insert You're IP Corecctly")
def remove(self):
index = self.ip_device_list.currentRow()
if index != -1:
self.ip_device_list.takeItem(index)
del self.device_list[index]
def runThread(self):
self.run_thread = sshConnection()
self.run_thread.finished.connect(app.exit)
self.run_thread.start()
app = QApplication(sys.argv)
app.setStyle('cleanlooks')
window = Widget()
window.show()
sys.exit(app.exec_())
QThread expects you to implement the run method, I think it is the same as runSSH but it is not, what you could do is call it in the run method, in the test that I show below I delete the line self.run_thread.finished.connect(app.exit)as it will close as soon as the print job does not take long.
class sshConnection(QThread):
def __init__(self):
QThread.__init__(self)
def __del__(self):
self.wait()
def run(self):
self.runSSH()
def runSSH(self):
#doo process
print('Haii')
for x in range(100):
print(x)

Categories

Resources