How to start multiple instances of function via pyqt5 button? - python

Hey i wrote an little AutoBuy Bot.
The GUI is made in PYQT5.
I have an button that calls an function with a few parameters.
The problem im running into is, that
the Main Window freezes
with problem nr1 i cant click the button multiple times to trigger the function multiple times.(I want to start it multiple times)
I really need some help with that.
my button :
self.buttonSoleBox = QPushButton('Start Bot', self)
self.buttonBox.move(20, 120)
self.buttonBox.clicked.connect(self.on_click)
and My Button action function:
def on_click(self):
email = self.textbox.text()
password = self.textbox1.text()
aid = self.textbox2.text()
payment = self.textbox4.text()
paypalemail = self.textbox5.text()
paypalpassword = self.textbox6.text()
StartBotFunction(email, password, aid, payment, paypalemail, paypalpassword)
self.textbox.setText("")
self.textbox1.setText("")
self.textbox2.setText("")
self.textbox4.setText("")
self.textbox5.setText("")
self.textbox6.setText("")
for testing:
2files:
main.py
from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QLineEdit, QLabel, QComboBox
from PyQt5 import QtGui
from selenium import webdriver
import sys
class App(QMainWindow):
def __init__(self):
super(App,self).__init__()
self.title = 'whatever'
self.left = 200
self.top = 200
self.width = 800
self.height = 500
self.setWindowIcon(QtGui.QIcon('icon.png'))
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.initUI()
def initUI(self):
self.button1 = QPushButton('Start Bot', self)
self.button1.move(20, 120)
self.button1.clicked.connect(self.on_click)
self.show()
def on_click(self):
word = "sneaker"
StartBotFunction(word)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
search.py
from selenium import webdriver
import time
def StartBotFunction(word):
word
driver = webdriver.Chrome()
driver.get('https://www.zalando.de/herren/?q=' + word )
first = driver.find_element_by_xpath('//*[#id="z-nvg-cognac-root"]/div[1]/z-grid/z-grid-item[2]/div/div[5]/z-grid/z-grid-item[1]/div/a')
first.click()
while (driver.page_source).__contains__('Bewertung'):
time.sleep(5)
driver.refresh()
while building that example for you, i found out that i run into my main problem when i do that
if i remove the while thing, i can create as many chromewindows as i click the button
Any idea how to fix that?
while (driver.page_source).__contains__('Bewertung'):
time.sleep(5)
driver.refresh()```

You have to run StartBotFunction in another thread:
import sys
import threading
from PyQt5 import QtCore, QtWidgets
import search
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
self.lineedit = QtWidgets.QLineEdit("sneaker", placeholderText="word")
button = QtWidgets.QPushButton("Press me")
button.clicked.connect(self.on_click)
flay = QtWidgets.QFormLayout(self)
flay.addRow("Insert word:", self.lineedit)
flay.addRow(button)
#QtCore.pyqtSlot()
def on_click(self):
word = self.lineedit.text()
threading.Thread(target=search.StartBotFunction, args=(word,)).start()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())

Related

PyQt5 - Application hangs when launching a separate QMainWindow using pynput

I'm trying to open a separate window using button combinations in pynput. I'm using the following code to open a new window and hide the original QMainWindow object. When the button is pressed, the logic works perfectly. But when I try to bind the same function to a combination of keyboard input, the application hangs. Anyone knows how I should approach this?
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton, QLabel)
from pynput import keyboard
class Window2(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Window22222")
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.title = "First Window"
self.top = 100
self.left = 100
self.width = 680
self.height = 500
self.pushButton = QPushButton("Start", self)
self.pushButton.move(275, 200)
self.pushButton.setToolTip("<h3>Start the Session</h3>")
self.pushButton.clicked.connect(self.window2)
self.main_window()
def main_window(self):
self.label = QLabel("Manager", self)
self.label.move(285, 175)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.show()
def hotkeys(self):
def on_activate_h():
self.window2()
def for_canonical(f):
return lambda k: f( l.canonical(k) )
h = keyboard.HotKey( keyboard.HotKey.parse( '<ctrl>+<alt>+h' ), on_activate_h )
l = keyboard.Listener( on_press=for_canonical(h.press), on_release=for_canonical(h.release) )
l.start()
def window2(self):
self.w = Window2()
self.w.show()
self.hide()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.hotkeys()
sys.exit(app.exec())

Python has stopped working when importing pywinauto package even I did not use it

I tried to use 'pywinauto' package and it works. But when I close app, python prompts an message "python has
stopped working". I added sys.coinit_flags = 2 as suggested by Vasily Ryabov, the warning disappeared.
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
import sys
import warnings
warnings.simplefilter("ignore", UserWarning)
sys.coinit_flags = 2
from pywinauto.application import Application
from pywinauto.keyboard import send_keys
class App(QWidget):
def __init__(self):
super(App,self).__init__()
self.title = 'PyQt5 button - pythonspot.com'
self.left = 10
self.top = 100
self.width = 320
self.height = 200
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
button = QPushButton('PyQt5 button', self)
button.setToolTip('This is an example button')
button.move(100, 70)
button.clicked.connect(self.on_click)
self.show()
def on_click(self):
print('PyQt5 button click')
def main():
app = QApplication(sys.argv)
app.setStyle('Fusion')
w = App()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
But when I tried to make the code complex, the warning message was prompted again if I clicked on first combo box to select value 'ar-prod'.
from PyQt5.QtCore import Qt
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
import sys
import warnings
warnings.simplefilter("ignore", UserWarning)
sys.coinit_flags = 2
from pywinauto.application import Application
from pywinauto.keyboard import send_keys
def main():
app = QApplication(sys.argv)
w = myView()
w.show()
sys.exit(app.exec_())
class myView(QWidget):
def __init__(self):
super(myView, self).__init__()
self.setGeometry(400, 200, 1000, 700)
self.mainLayout = QVBoxLayout()
self.splitter1 = QSplitter(Qt.Horizontal)
# Add ComboBox
self.cb1=QComboBox() #ar-dev or ar-prod
self.cb1.addItems(['ar-dev','ar-prod'])
self.cb2=QComboBox() #ar-dev/.
self.cb3=QComboBox() #ar-dev/..
self.cb4=QComboBox() #ar-dev/...
self.btn=QPushButton('Launch SAS EG')
self.splitter1.addWidget(self.cb1)
self.splitter1.addWidget(self.cb2)
self.splitter1.addWidget(self.cb3)
self.splitter1.addWidget(self.cb4)
self.splitter1.addWidget(self.btn)
# Add list of folders
self.splitter2 = QSplitter(Qt.Vertical)
self.bottomleft_layout = QHBoxLayout()
self.GroupBox1 = QGroupBox("")
self.table = QTableWidget()
self.table.verticalHeader().setVisible(False)
self.table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # close vertical scroll bar
self.table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # close horizontal scroll bar
self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.table.verticalHeader().setSectionResizeMode(QHeaderView.Stretch)
self.hfont = QFont('Times New Roman', 12)
self.hfont.setBold(True)
self.table.horizontalHeader().setFont(self.hfont)
style = "::section {""background-color: lightgray; }"
self.table.horizontalHeader().setStyleSheet(style)
self.table.horizontalHeader().setFixedHeight(50)
self.bottomleft_layout.addWidget(self.table)
self.GroupBox1.setLayout(self.bottomleft_layout)
# Add Autoexec
self.GroupBox2 = QGroupBox("")
self.bottomright_layout = QVBoxLayout()
self.textEdit = QTextEdit()
self.bottomright_layout.addWidget(self.textEdit)
self.GroupBox2.setLayout(self.bottomright_layout)
self.tabs = QTabWidget()
self.tabs.addTab(self.GroupBox1, 'Hyperlinks to Sub Folders')
self.tabs.addTab(self.GroupBox2, 'Autoexec')
self.splitter2.addWidget(self.tabs)
self.mainLayout.addWidget(self.splitter1)
self.mainLayout.addWidget(self.splitter2)
self.setLayout(self.mainLayout)
if __name__ == '__main__':
main()
Here is the warning message.
If I remove self.cb1.addItems(['ar-dev', 'ar-prod']) and do not populate first combo box, the error will not occur.
You need sys.coinit_flags = 2 before importing pywinauto. Like it is shown here: https://github.com/pywinauto/py_inspect/blob/master/py_inspect.py

QWebEngineView history canGoForward/canGoBack works only after three items

I have a simple application where the back and forward buttons are enabled/disabled based on the history of the visited web pages. For this, I have found the canGoForward and canGoBack functions
of the QWebEngineHistory. However, the functions return True only after there are at least three items in the history. Normally, browsers work right after visiting the second different page.
Is this supposed to be working like that? I there any way to change it to the 2 web pages? I have looked at the QWebEngineSettings, but there is nothing related to this.
Here is a working example:
#!/usr/bin/python
import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import (QApplication, QLineEdit, QMainWindow,
QPushButton, QToolBar)
from PyQt5.QtWebEngineWidgets import QWebEnginePage, QWebEngineView
class Example(QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.toolBar = QToolBar(self)
self.addToolBar(self.toolBar)
self.backBtn = QPushButton(self)
self.backBtn.setEnabled(False)
self.backBtn.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/left-32.png'))
# self.backBtn.setIcon(QIcon('stock_left.png'))
self.backBtn.clicked.connect(self.back)
self.toolBar.addWidget(self.backBtn)
self.forBtn = QPushButton(self)
self.forBtn.setEnabled(False)
# self.forBtn.setIcon(QIcon('stock_right.png'))
self.forBtn.setIcon(QIcon(':/qt-project.org/styles/commonstyle/images/right-32.png'))
self.forBtn.clicked.connect(self.forward)
self.toolBar.addWidget(self.forBtn)
self.address = QLineEdit(self)
self.address.returnPressed.connect(self.load)
self.toolBar.addWidget(self.address)
self.webEngineView = QWebEngineView(self)
self.setCentralWidget(self.webEngineView)
self.webEngineView.page().urlChanged.connect(self.onLoadFinished)
print(self.webEngineView.history().backItem().url())
print(self.webEngineView.history().forwardItem().url())
self.setGeometry(300, 300, 500, 400)
self.setWindowTitle('QWebEnginePage')
self.show()
# self.webEngineView.page().urlChanged.connect(self.urlChanged)
def onLoadFinished(self):
print(dir(self.webEngineView.history()))
print('load finished')
# print(self.webEngineView.history().backItem().url())
# print(self.webEngineView.history().forwardItem().url())
# print(self.webEngineView.history().backItem())
# print(self.webEngineView.history().forwardItem())
# print(self.webEngineView.history().count())
# print(self.webEngineView.history().items())
# print(self.webEngineView.history().canGoForward())
# print(self.webEngineView.history().canGoBack())
if self.webEngineView.history().canGoBack():
self.backBtn.setEnabled(True)
else:
self.backBtn.setEnabled(False)
if self.webEngineView.history().canGoForward():
self.forBtn.setEnabled(True)
else:
self.forBtn.setEnabled(False)
def load(self):
url = QUrl.fromUserInput(self.address.text())
if url.isValid():
self.webEngineView.load(url)
def back(self):
self.webEngineView.page().triggerAction(QWebEnginePage.Back)
def forward(self):
self.webEngineView.page().triggerAction(QWebEnginePage.Forward)
def urlChanged(self, url):
self.address.setText(url.toString())
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

How to use threading in a function to preventing gui from freezing? [duplicate]

This question already has an answer here:
how i can make thread for progress bar with pafy
(1 answer)
Closed 2 years ago.
I'm making a simple audio downloader from video,but whenever i click download button gui stops until downloading has finished.
I thought i can use threading for kind of these things but almost there are hundreds of method to achieve that,but i don't know which one i should choose and that's why I'm so confused then wanted to ask you.
My code here:
import sys
import threading
import pafy
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 button - pythonspot.com'
self.left = 100
self.top = 100
self.width = 320
self.height = 200
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
button = QPushButton('Coffee shop radio', self)
button.move(10,10)
button.clicked.connect(self.on_click)
self.show()
def on_click(self):
url = "https://www.youtube.com/watch?v=IcvruhYk0po"
video = pafy.new(url)
bestaudio = video.getbestaudio()
bestaudio.download()
if __name__ == '__main__':
app = QApplication([])
ex = App()
sys.exit(app.exec_())
Have changed the code a little and it works,thanks for everyone.
import sys
import threading
import pafy
from time import sleep
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLineEdit
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
class App(QWidget):
threads = []
def __init__(self):
super().__init__()
self.title = 'YouDio'
self.left = 100
self.top = 100
self.width = 280
self.height = 90
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
button = QPushButton('DOWNLOAD', self)
button.move(10,25)
button.clicked.connect(self.on_click)
self.line = QLineEdit(self)
self.line.move(120,27)
self.show()
def on_click(self):
self.t = threading.Thread(target=self.threaded)
self.t.start()
def threaded(self):
url = self.line.text()
video = pafy.new(url)
bestaudio = video.getbestaudio()
bestaudio.download()
if __name__ == '__main__':
app = QApplication([])
ex = App()
sys.exit(app.exec_())
from threading import Thread
import sys
import threading
import pafy
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import pyqtSlot
def download_me():
url = "https://www.youtube.com/watch?v=IcvruhYk0po"
video = pafy.new(url)
bestaudio = video.getbestaudio()
bestaudio.download()
class App(QWidget):
def __init__(self):
super().__init__()
self.title = 'PyQt5 button - pythonspot.com'
self.left = 100
self.top = 100
self.width = 320
self.height = 200
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
button = QPushButton('Coffee shop radio', self)
button.move(10,10)
button.clicked.connect(self.on_click)
self.show()
def on_click(self):
t = Thread(target=download_me)
t.daemon = True
t.start()
if __name__ == '__main__':
app = QApplication([])
ex = App()
sys.exit(app.exec_())
try this!
In fact download task is done synchronously so your theard will block until the download task is over...you have to put this part of your code inside a daemon thread.
Note: I don't know if python thread can be mixed with Qt so you should use the good Lib but the idea remains the same

Add different text to a window

I have a button and a text label. Each time the button is pressed, i would like text placed from a line edit to be placed onto the window. So far I can only get one text to draw onto the window, even if I create another textlabel. Ive tried seeting a click count determining how many times a user has clicked a button but this doesnt work either. Heres what I have so far, any suggestions?
import sys
import os
from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtGui import QApplication
class Window(QMainWindow):
def __init__(self, *args):
QMainWindow.__init__(self, *args)
self.centralWidget = QWidget(self)
self.setCentralWidget(self.centralWidget)
self.setGeometry(450,100,350,680)
self.btn1 = QPushButton("Enter", self.centralWidget)
self.btn1.setGeometry(10,50,150, 20)
self.btn1.clicked.connect(self.enter)
self.edit = QtGui.QLineEdit(self)
self.edit.setGeometry(10, 10, 150, 20)
self.label = QtGui.QLabel(self)
self.label.setGeometry(240, 170,150, 20)
def enter(self):
self.label.setText(self.edit.text())
def main(args):
global app
app = App(args)
app.exec_()
class App(QApplication):
def __init__(self, *args):
QApplication.__init__(self, *args)
self.main = Window()
self.connect(self, SIGNAL("lastWindowClosed()"), self.byebye )
self.main.show()
def byebye( self ):
self.exit(0)
if __name__ == "__main__":
main(sys.argv)
There are a few problems with your example code, the main one being that you are trying to manually arrange the widgets, rather than using a layout.
It's hard to tell from your question exactly what you expect the output to be, so I've assumed you want the text from line-edit to be appended to the label, so that you end up with a series of lines.
Here's a simplified version of your example that hopefully does what you want:
from PyQt4 import QtCore, QtGui
class Window(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.btn1 = QtGui.QPushButton("Enter", self)
self.btn1.clicked.connect(self.enter)
self.edit = QtGui.QLineEdit(self)
self.label = QtGui.QLabel(self)
self.label.setAlignment(
QtCore.Qt.AlignTop | QtCore.Qt.AlignLeft)
widget = QtGui.QWidget(self)
layout = QtGui.QVBoxLayout(widget)
layout.addWidget(self.edit)
layout.addWidget(self.btn1)
layout.addWidget(self.label)
self.setCentralWidget(widget)
def enter(self):
text = self.edit.text()
if text:
self.label.setText('%s\n%s' % (self.label.text(), text))
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(450, 100, 350, 680)
window.show()
sys.exit(app.exec_())

Categories

Resources