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")
Related
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()
I'm trying to write a Python program using PyQt5 that will display a window in each iteration of the for loop. I would like to close after incrementing and displaying the next window. However, I do not know how to stop the loop every iteration and at the moment I am getting 6 windows at once.
main.py
import sys
from PyQt5.QtWidgets import (QLineEdit, QVBoxLayout, QMainWindow,
QWidget, QDesktopWidget, QApplication, QPushButton, QLabel,
QComboBox, QFileDialog, QRadioButton)
from PyQt5.QtCore import pyqtSlot, QByteArray
from alert import Window2
from test import test
class SG(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.resize(300, 150)
self.setWindowTitle('TEST')
self.resultsGen = QPushButton('TEST', self)
self.resultsGen.clicked.connect(lambda: self.on_click())
self.show()
#pyqtSlot()
def on_click(self):
test(self)
if __name__ == '__main__':
app = QApplication(sys.argv)
sg = SG()
sys.exit(app.exec_())
alert.py
from PyQt5.QtWidgets import (QLineEdit, QVBoxLayout, QMainWindow,
QWidget, QDesktopWidget, QApplication, QPushButton, QLabel,
QComboBox, QFileDialog, QRadioButton)
from PyQt5.QtCore import pyqtSlot, QByteArray
from PyQt5.QtGui import QPixmap
from PyQt5 import QtGui, QtCore
class Window2(QMainWindow):
def __init__(self):
super().__init__()
self.initPopup()
def initPopup(self):
self.resize(500, 500)
self.setWindowTitle("Window22222")
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
lay = QVBoxLayout(self.central_widget)
label = QLabel(self)
pixmap = QPixmap('cropped/8.png')
label.setPixmap(pixmap)
self.resize(pixmap.width(), pixmap.height())
lay.addWidget(label)
self.textbox = QLineEdit(self)
self.textbox.move(20, 20)
self.textbox.resize(280, 40)
# Create a button in the window
self.button = QPushButton('Show text', self)
self.button.move(20, 80)
# connect button to function on_click
self.button.clicked.connect(lambda: self.on_clickX())
self.show()
#pyqtSlot()
def on_clickX(self):
textboxValue = self.textbox.text()
print(textboxValue)
self.textbox.setText("")
self.hide()
test.py
from alert import Window2
def test(self):
for x in range(6):
w = Window2()
As soon as you run the for cycle, all the code of the initialization will be executed, which includes the show() call you used at the end of initPopup().
A simple solution is to create a new signal that is emitted whenever you hide a window, and connect that signal to a function that creates a new one until it reaches the maximum number.
main.py:
import sys
from PyQt5.QtWidgets import QWidget, QApplication, QPushButton
from alert import Window2
class SG(QWidget):
def __init__(self):
super().__init__()
self.initUI()
self.alerts = []
def initUI(self):
self.resize(300, 150)
self.setWindowTitle('TEST')
self.resultsGen = QPushButton('TEST', self)
self.resultsGen.clicked.connect(self.nextAlert)
self.show()
def nextAlert(self):
if len(self.alerts) >= 6:
return
alert = Window2()
self.alerts.append(alert)
alert.setWindowTitle('Window {}'.format(len(self.alerts)))
alert.closed.connect(self.nextAlert)
alert.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
sg = SG()
sys.exit(app.exec_())
alert.py:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Window2(QMainWindow):
closed = pyqtSignal()
def __init__(self):
super().__init__()
self.initPopup()
def initPopup(self):
self.resize(500, 500)
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
lay = QVBoxLayout(self.central_widget)
label = QLabel(self)
pixmap = QPixmap('cropped/8.png')
label.setPixmap(pixmap)
self.resize(pixmap.width(), pixmap.height())
lay.addWidget(label)
self.textbox = QLineEdit(self)
lay.addWidget(self.textbox)
# Create a button in the window
self.button = QPushButton('Show text', self)
lay.addWidget(self.button)
# connect button to function on_click
self.button.clicked.connect(lambda: self.on_clickX())
self.show()
#pyqtSlot()
def on_clickX(self):
textboxValue = self.textbox.text()
print(textboxValue)
self.textbox.setText("")
self.hide()
self.closed.emit()
Just note that with this very simplified example the user might click on the button of the "SG" widget even if an "alert" window is visibile. You might prefer to use a QDialog instead of a QMainWindow and make the main widget a parent of that dialog.
main.py:
class SG(QWidget):
# ...
def nextAlert(self):
if len(self.alerts) >= 6:
return
alert = Window2(self)
# ...
alert.py:
class Window2(QDialog):
closed = pyqtSignal()
def __init__(self, parent):
super().__init__()
self.initPopup()
def initPopup(self):
self.resize(500, 500)
# a QDialog doesn't need a central widget
lay = QVBoxLayout(self)
# ...
Also, if an alert window is closed using the "X" button the new one will not be shown automatically. To avoid that, you can implement the "closeEvent" and ignore the event, so that the user will not be able to close the window until the button is clicked. As QDialogs can close themself when pressing the escape key, I'm also ignoring that situation.
alert.py:
class Window2(QMainWindow):
# ...
def closeEvent(self, event):
event.ignore()
def keyPressEvent(self, event):
if event.key() != Qt.Key_Escape:
super().keyPressEvent(event)
I'm trying to capture Text with a click on a QPushButton and Display it in a QLabel with pyqt5
I really new to this stuff so go easy on me !
here is the code I have so far:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel, QLineEdit
from PyQt5.QtCore import pyqtSlot
class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
hbox = QHBoxLayout()
game_name = QLabel("Game Name:", self)
game_line_edit = QLineEdit(self)
search_button = QPushButton("Search", self)
search_button.clicked.connect(self.on_click)
hbox.addWidget(game_name)
hbox.addWidget(game_line_edit)
hbox.addWidget(search_button)
self.setLayout(hbox)
self.show()
#pyqtSlot()
def on_click(self):
game = QLabel(game_line_edit.text(), self)
hbox.addWidget(game)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
I keep getting this error:
game = QLabel(game_line_edit.text(), self)
NameError: name 'game_line_edit' is not defined
I am not sure why game_line_edit is not defined but have a feeling it's because it not is the same "class" as my on_click class but am not sure
any help would be appreciated
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QHBoxLayout, QPushButton, QLabel, QLineEdit
from PyQt5.QtCore import pyqtSlot
class Window(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.hbox = QHBoxLayout()
self.game_name = QLabel("Game Name:", self)
self.game_line_edit = QLineEdit(self)
self.search_button = QPushButton("Search", self)
self.search_button.clicked.connect(self.on_click)
self.hbox.addWidget(self.game_name)
self.hbox.addWidget(self.game_line_edit)
self.hbox.addWidget(self.search_button)
self.setLayout(self.hbox)
self.show()
#pyqtSlot()
def on_click(self):
game = QLabel(self.game_line_edit.text(), self)
self.hbox.addWidget(game)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = Window()
sys.exit(app.exec_())
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_())
Hi everyone.
I am making a GUI application using python3.4, PyQt5 in windows 7.
Application is very sample. User clicks a main window's button, information dialog pops up. And when a user clicks information dialog's close button (window's X button), system shows confirm message. This is all.
Here's my code.
# coding: utf-8
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QLabel
class mainClass(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
openDlgBtn = QPushButton("openDlg", self)
openDlgBtn.clicked.connect(self.openChildDialog)
openDlgBtn.move(50, 50)
self.setGeometry(100, 100, 200, 200)
self.show()
def openChildDialog(self):
childDlg = QDialog(self)
childDlgLabel = QLabel("Child dialog", childDlg)
childDlg.resize(100, 100)
childDlg.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
mc = mainClass()
sys.exit(app.exec_())
Result screen shot is...
In this situation, I've added these code in mainClass class.
def closeEvent(self, event):
print("X is clicked")
This code works only when the main window is closed. But what I want is closeEvent function works when childDlg is to closed. Not main window.
What should I do?
You have added, the method closeEvent in the class mainClass.
So you have reimplemented the method closeEvent of your QMainwindow and not the method closeEvent of your childDlg. To do it, you have to subclass your chilDlg like this:
# coding: utf-8
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QLabel
class ChildDlg(QDialog):
def closeEvent(self, event):
print("X is clicked")
class mainClass(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
openDlgBtn = QPushButton("openDlg", self)
openDlgBtn.clicked.connect(self.openChildDialog)
openDlgBtn.move(50, 50)
self.setGeometry(100, 100, 200, 200)
self.show()
def openChildDialog(self):
childDlg = ChildDlg(self)
childDlgLabel = QLabel("Child dialog", childDlg)
childDlg.resize(100, 100)
childDlg.show()
if __name__ == "__main__":
app = QApplication(sys.argv)
mc = mainClass()
sys.exit(app.exec_())
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QDialog, QLabel
class mainClass(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
openDlgBtn = QPushButton("openDlg", self)
openDlgBtn.clicked.connect(self.openChildDialog)
openDlgBtn.move(50, 50)
self.setGeometry(100, 100, 200, 200)
self.show()
def openChildDialog(self):
childDlg = QDialog(self)
childDlgLabel = QLabel("Child dialog", childDlg)
childDlg.closeEvent = self.CloseEvent
childDlg.resize(100, 100)
childDlg.show()
def CloseEvent(self, event):
print("X is clicked")
if __name__ == "__main__":
app = QApplication(sys.argv)
mc = mainClass()
sys.exit(app.exec_())