import sys
from PyQt5 import QtCore
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QMainWindow, QApplication, QPlainTextEdit, QApplication, QMainWindow, QLabel, QComboBox
from PyQt5.QtGui import QPixmap
from pynput import keyboard
from pynput.keyboard import Listener, Controller
import pyperclip as pc
keyboard = Controller()
class App(QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent)
#super().__init__()
label = QLabel(self)
pixmap = QPixmap('E:/copycat/new.png')
label.setPixmap(pixmap)
label.setGeometry(0,0,900,400)
self.title = 'COPYCAT'
self.left = 10
self.top = 10
self.width = 400
self.height = 140
self.initUI()
self.key()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
###########
combo = QComboBox(self)
shotcut_list = ["Key.f9","Key.f2","Key.f3","Key.f4","Key.f5","Key.f6","Key.f7","Key.f8","Key.f1","Key.f10","Key.f11","Key.f12"]
combo.addItems(shotcut_list)
global shortcut
global cptext
shortcut = combo.currentText()
combo.setGeometry(350, 120, 120, 30)
combo.activated[str].connect(self.onChanged)
# Create textbox
self.textbox = QPlainTextEdit(self)
self.textbox.move(20, 160)
self.textbox.setReadOnly(True)
self.textbox.resize(500,205)
self.setGeometry(70,70,540,388)
self.show()
def onChanged(self, text):
global shortcut
shortcut=text
def print_key(self,key):
if str(key) == shortcut:
cptext = pc.paste()
keyboard.type(cptext)
self.textbox.insertPlainText(cptext)
self.textbox.insertPlainText("\n")
def key(self):
listener = Listener(on_press=self.print_key)
listener.start()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
ex = App()
#ex.key()
sys.exit(app.exec_())
The above code shows an error when I update the textbox from the print_key function
It shows this error:
Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType()
Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType()
The callback associated with on_press is executed in a secondary thread so your implementation is updating the GUI from a secondary thread which Qt prohibits, instead you should use the signals as they are thread-safe.
import sys
import threading
from PyQt5.QtCore import pyqtSignal, pyqtSlot, QObject
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import (
QApplication,
QComboBox,
QLabel,
QMainWindow,
QPlainTextEdit,
)
from pynput.keyboard import Listener, Controller
import pyperclip as pc
class KeyboardListener(QObject):
textChanged = pyqtSignal(str)
def __init__(self, shortcut, parent=None):
super().__init__(parent)
self._shortcut = shortcut
listener = Listener(on_press=self.handle_pressed)
listener.start()
self.mutex = threading.Lock()
#property
def shortcut(self):
return self._shortcut
def handle_pressed(self, key):
with self.mutex:
if str(key) == self.shortcut:
cptext = pc.paste()
self.textChanged.emit(cptext)
#pyqtSlot(str)
def update_shortcut(self, shortcut):
with self.mutex:
self._shortcut = shortcut
class App(QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent)
# super().__init__()
label = QLabel(self)
pixmap = QPixmap("E:/copycat/new.png")
label.setPixmap(pixmap)
label.setGeometry(0, 0, 900, 400)
self.title = "COPYCAT"
self.left = 10
self.top = 10
self.width = 400
self.height = 140
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
###########
combo = QComboBox(self)
shotcut_list = [
"Key.f9",
"Key.f2",
"Key.f3",
"Key.f4",
"Key.f5",
"Key.f6",
"Key.f7",
"Key.f8",
"Key.f1",
"Key.f10",
"Key.f11",
"Key.f12",
]
combo.addItems(shotcut_list)
shortcut = combo.currentText()
combo.setGeometry(350, 120, 120, 30)
self.textbox = QPlainTextEdit(self)
self.textbox.move(20, 160)
self.textbox.setReadOnly(True)
self.textbox.resize(500, 205)
self.setGeometry(70, 70, 540, 388)
self.keyboard = Controller()
self.listener = KeyboardListener(combo.currentText())
combo.activated[str].connect(self.listener.update_shortcut)
self.listener.textChanged.connect(self.handle_text_changed)
#pyqtSlot(str)
def handle_text_changed(self, text):
self.textbox.insertPlainText(text)
self.textbox.insertPlainText("\n")
self.keyboard.type(text)
def main():
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
Related
I am dealing with the following problem, while I am having multiple windows open, i would like to build a function linked to a button to bring to the front the Main window.
Thank you in advance.
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QLabel)
class Window2(QMainWindow): # <===
def __init__(self):
super().__init__()
self.setWindowTitle("Window 2")
self.pushButton = QPushButton("Back to window1", self)
self.pushButton.clicked.connect(self.window1)
def window1(self): # <===
pass;
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("Go to window 2 ", self)
self.pushButton.move(275, 200)
self.label = QLabel("window 1", self)
self.label.move(285, 175)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.pushButton.clicked.connect(self.window2) # <===
def window2(self): # <===
self.w = Window2()
self.w.show()
def main():
app = QApplication(sys.argv)
window = Window()
window.show()
#app.exec_()
exit(app.exec_())
if __name__=='__main__':
main()
Regards
I am expecting a function to call back the widget "Window"
You could emit a signal from your second window that your fist window listens for, and calls .raise_() when triggered.
Update: Added a call to activateWindow in the first windows callback. thanks #musicmante
For example:
import sys
from PyQt5 import QtGui
from PyQt5.QtCore import pyqtSignal # import signal
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QLabel)
class Window2(QMainWindow):
unfocus = pyqtSignal() # create signal
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setWindowTitle("Window 2")
self.pushButton = QPushButton("Back to window1", self)
# button press emits signal
self.pushButton.clicked.connect(self.unfocus.emit)
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("Go to window 2 ", self)
self.pushButton.move(275, 200)
self.label = QLabel("window 1", self)
self.label.move(285, 175)
self.setWindowTitle(self.title)
self.setGeometry(self.top, self.left, self.width, self.height)
self.pushButton.clicked.connect(self.window2) # <===
def window2(self): # <===
self.w = Window2()
self.w.unfocus.connect(self.bring_to_top) # listen for signal and raise_ to top focus
self.w.show()
def bring_to_top(self):
self.activateWindow()
self.raise_()
def main():
app = QApplication(sys.argv)
window = Window()
window.show()
#app.exec_()
exit(app.exec_())
if __name__=='__main__':
main()
i use the code below, found on stackoverflow. i want to build a loop which getting started with a button on the main window. After clicked window2 should open for 30 seconds. then window3 should open for 30 seconds. then window2 should open and so on.
i make a slide methode but it wont work.
i try it with the window2() and window3() and slide() methode
what is my target?
i want a slideshow with the two window(window2 & window3) that alternate.
not more but it is an endless loop
import sys
from PyQt5 import QtGui
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QToolTip, QMessageBox, QLabel)
class Window2(QMainWindow): # <===
def __init__(self):
super().__init__()
self.setWindowTitle("Window22222")
class Window3(QMainWindow): # <===
def __init__(self):
super().__init__()
self.setWindowTitle("Window333333")
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.pushButton1 = QPushButton("Start", self)
self.pushButton1.move(20, 20)
self.pushButton1.setToolTip("<h3>Start the Session</h3>")
self.pushButton1.clicked.connect(self.slide)
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 window2(self): # <===
self.w2 = Window2()
self.w2.show()
time.sleep(5)
self.w3 = Window3()
self.w3.show()
self.w2.hide()
self.window3()
#self.hide()
def window3(self): # <===
self.w3 = Window3()
self.w3.show()
time.sleep(5)
self.w2 = Window2()
self.w2.show()
self.w3.hide()
self.window2()
#self.hide()
def slide(self):
print ("slide")
self.window2()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
sys.exit(app.exec())
Try it:
import sys
#import time
from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import (QApplication, QMainWindow, QPushButton,
QToolTip, QMessageBox, QLabel)
class Window2(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Window 22222")
class Window3(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("Window 333333")
class Window(QMainWindow):
def __init__(self):
super().__init__()
self.title = "First Window"
self.top, self.left, self.width, self.height = 100, 100, 680, 500
self.flag = ...
self.pushButton = QPushButton("Start", self)
self.pushButton.move(275, 200)
self.pushButton.setToolTip("<h3>Start the Session</h3>")
self.pushButton.clicked.connect(lambda: self.start_slide(True)) #(self.window2)
self.pushButton1 = QPushButton("Start", self)
self.pushButton1.move(20, 20)
self.pushButton1.setToolTip("<h3>Start the Session</h3>")
self.pushButton1.clicked.connect(lambda: self.start_slide(False))
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self.main_window()
self.w2 = Window2()
self.w3 = Window3()
self.timer = QtCore.QTimer(self)
self.timer.timeout.connect(self.viewWindows)
def start_slide(self, flag):
self.timer.stop()
self.w3.hide()
self.w2.hide()
if flag: self.w2.show()
else: self.w3.show()
self.flag = not flag
self.timer.start(5000)
def viewWindows(self):
if self.flag:
self.w2.show()
self.w3.hide()
else:
self.w3.show()
self.w2.hide()
self.flag = not self.flag
def closeEvent(self, event):
self.w2.close()
self.w3.close()
self.close()
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
I make a program using PyQt5 and Python3.7. How to move across elements using arrow keys instead of tab key? (e.g. moving from button to textbox using down key)
import sys
from PyQt5.QtWidgets import QApplication, QLabel, QLineEdit, QMainWindow, QPushButton, QFileSystemModel, QTreeView, \
QFileDialog, QComboBox
from PyQt5.QtCore import pyqtSlot
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.title = 'by Qt5 and python 3.7'
self.left = 10
self.top = 10
self.width = 1000
self.height = 500
self.initUI()
def initUI(self):
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.label = QLabel('File Name: ')
self.label.move(20, 20)
self.btn_browse = QPushButton('Browse', self)
self.btn_browse.move(50, 20)
self.btn_browse.clicked.connect(self.on_click)
self.textbox = QLineEdit(self)
self.textbox.move(170, 20)
self.textbox.resize(280, 40)
self.page_view = QLineEdit(self)
self.page_view.move(20, 100)
self.page_view.resize(800, 400)
self.show()
#pyqtSlot()
def on_click(self):
print('PyQt5 button click')
# self.openFileNameDialog()
# self.saveFileDialog()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
One possible solution is to overwrite the keyPressEvent() method to detect the desired key and use focusNextPrevChild() by passing False or True if you want the focus to go to the previous or next widget, respectively.
from PyQt5.QtCore import pyqtSlot, Qt
class App(QMainWindow):
# ...
def keyPressEvent(self, e):
if e.key() == Qt.Key_Down:
self.focusNextPrevChild(True)
elif e.key() == Qt.Key_Up:
self.focusNextPrevChild(False)
# ...
I understand that to use a global variable from a function, you Need to execute the function first:
def f():
global s
s = 'Hello'
f()
print(s)
But how do I use variable s globally in following example:
import sys
from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, QLineEdit, QLabel, QComboBox, QProgressBar, QFileDialog
from PyQt4.QtCore import QSize, pyqtSlot
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.setGeometry(500, 300, 820, 350)
self.setWindowTitle("Widget")
self.initUI()
def initUI(self):
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('GetValue', self)
self.btn4.move(btnposx,btnposy+220)
self.btn4.clicked.connect(self.cb_get)
self.cb = QComboBox(self)
self.cb.move(btnposx+120,btnposy+150)
self.cb.resize(80,22)
self.cb.setMaximumSize(QSize(80,1000000))
self.cb.addItem('A')
self.cb.addItem('B')
self.cb.addItem('C')
self.cb.addItem('D')
self.cb.addItem('E')
self.show()
#pyqtSlot()
def cb_get(self):
global s
cbtext = str(self.cb.currentText())
s = cbtext
print(s)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
This code shows a PyQt4 Widget. Function cb_get acquires the Value of a QcomboBox and can be used within the class App(). The Value is saved to variable s. How do I use variable s globally?
The only way I seem to get it to work is to write a new function for s and execute it on button click:
import sys
from PyQt4.QtGui import QApplication, QMainWindow, QPushButton, QLineEdit, QLabel, QComboBox, QProgressBar, QFileDialog
from PyQt4.QtCore import QSize, pyqtSlot
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.setGeometry(500, 300, 820, 350)
self.setWindowTitle("Widget")
self.initUI()
def initUI(self):
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('GetValue', self)
self.btn4.move(btnposx,btnposy+220)
self.btn4.clicked.connect(self.cb_get)
self.btn4.clicked.connect(self.p)
self.cb = QComboBox(self)
self.cb.move(btnposx+120,btnposy+150)
self.cb.resize(80,22)
self.cb.setMaximumSize(QSize(80,1000000))
self.cb.addItem('A')
self.cb.addItem('B')
self.cb.addItem('C')
self.cb.addItem('D')
self.cb.addItem('E')
self.show()
#pyqtSlot()
def cb_get(self):
global s
s = str(self.cb.currentText())
def p(self):
print(s)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())
Well, at least now it has ist own function and I can write code for it seperately.
def initUI(self):
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('GetValue', self)
self.btn4.move(btnposx,btnposy+220)
self.btn4.clicked.connect(self.cb_get)
self.cb = QComboBox(self)
self.cb.move(btnposx+120,btnposy+150)
self.cb.resize(80,22)
self.cb.setMaximumSize(QSize(80,1000000))
self.cb.addItem('A')
self.cb.addItem('B')
self.cb.addItem('C')
self.cb.addItem('D')
self.cb.addItem('E')
self.s = None # initialize it here so you don't have to use global
self.show()
#pyqtSlot()
def cb_get(self):
cbtext = str(self.cb.currentText())
self.s = cbtext
def get_s(self):
return self.s
and
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
# print(ex.get_s) # this won't work since you have to click on btn4 first
sys.exit(app.exec_())
I have a program. When I click on the "Hello" button, my cursor changes (within 5 seconds) (the cursor is the mouse cursor). Is this a bug or am I doing something wrong? Why does my cursor change for five seconds? What can I do to keep the cursor from changing?
import sys
from PyQt5.QtWidgets import QMainWindow, QAction, qApp, QApplication, QPushButton,QLabel
from PyQt5.QtCore import QCoreApplication
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QTime, QTimer, Qt, QRect
class Example2(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.statusBar()
self.setGeometry(300, 300, 300, 200)
btn2 = QPushButton("Cat", self)
btn2.resize(btn2.sizeHint())
btn2.move(50,50)
btn2.clicked.connect(self.buttonClicked)
lbl1 = QLabel("We like it", self)
lbl1.setGeometry(QRect(50, 30, 150, 50))
lbl1.setScaledContents(True)
lbl1.updateGeometry()
lbl1.adjustSize()
self.show()
def buttonClicked(self):
pass
class Example1(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.statusBar()
self.setGeometry(300, 300, 300, 200)
btn1 = QPushButton("Hello", self)
btn1.resize(btn1.sizeHint())
btn1.move(50, 85)
btn1.clicked.connect(self.buttonClicked)
self.show()
def buttonClicked(self):
sender = self.sender()
if sender.text() == 'Hello':
self.hide()
self.Example2 = Example2()
self.Example2.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example1()
sys.exit(app.exec_())
print("Hello")