This question already has an answer here:
Get text from qtextedit and assign it to a variable
(1 answer)
Closed 4 years ago.
whenever I click a button in the second window of my PyQt5 application that should just print the value of a QDateEdit in the GUI, it closes with the line: "Process finished with exit code -1073740791 (0xC0000409)". I figured out that the problem has something to do with the .value() method. Here's the Minimal to reproduce the bug with the Ui_Form class below:
import sys
from PyQt5 import QtWidgets
from ui.fenster import Ui_Form
app = QtWidgets.QApplication(sys.argv)
class AppendWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
self.ui.submit.clicked.connect(self.show_value)
def show_value(self):
print(self.ui.date.value())
append = AppendWindow()
append.show()
sys.exit(app.exec_())
Ui_Form:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(413, 215)
self.date = QtWidgets.QDateEdit(Form)
self.date.setGeometry(QtCore.QRect(72, 26, 321, 20))
self.date.setObjectName("date")
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(9, 26, 57, 16))
self.label.setObjectName("label")
self.age = QtWidgets.QSpinBox(Form)
self.age.setGeometry(QtCore.QRect(70, 120, 321, 20))
self.age.setObjectName("age")
self.label_2 = QtWidgets.QLabel(Form)
self.label_2.setGeometry(QtCore.QRect(10, 120, 23, 16))
self.label_2.setObjectName("label_2")
self.label_3 = QtWidgets.QLabel(Form)
self.label_3.setGeometry(QtCore.QRect(9, 69, 27, 16))
self.label_3.setObjectName("label_3")
self.name = QtWidgets.QPlainTextEdit(Form)
self.name.setGeometry(QtCore.QRect(72, 69, 319, 21))
self.name.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.name.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
self.name.setObjectName("name")
self.submit = QtWidgets.QPushButton(Form)
self.submit.setGeometry(QtCore.QRect(170, 170, 75, 23))
self.submit.setObjectName("submit")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "Geburtsjahr"))
self.label_2.setText(_translate("Form", "Alter"))
self.label_3.setText(_translate("Form", "Name"))
self.submit.setText(_translate("Form", "Absenden!"))
Does anyone know how to fix this?
I appreciate your help!
You need to add app.exec() in your main code in order to start the main loop.
app = QtWidgets.QApplication(sys.argv)
app.exec()
The main loop handles all the incoming events and passes them to your GUI elements.
Related
I have a simple pyqt5 script that makes the following UI:
UI
The python file for this code is named 'Test.py' and is as follows:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(400, 400)
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(150, 90, 91, 31))
self.label.setObjectName("label")
self.lineEdit = QtWidgets.QLineEdit(Form)
self.lineEdit.setGeometry(QtCore.QRect(240, 100, 113, 20))
self.lineEdit.setObjectName("lineEdit")
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(250, 150, 75, 23))
self.pushButton.setObjectName("pushButton")
self.pushButton.clicked.connect(self.function) #<<<<<<<< MY INPUT
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.label.setText(_translate("Form", "Job Number"))
self.pushButton.setText(_translate("Form", "Press it"))
def function(self): #<<<<<<<< MY INPUT
self.text = self.lineEdit.text() #<<<<<<<< MY INPUT
return self.text #<<<<<<<< MY INPUT
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
I simply want to use the 'self.text' value that is generated on a different python file called 'Test1.py'.
I tried tried the following in the 'Test1.py' file:
from Test import Ui_Form
obj = Ui_Form()
obj.function()
But I keep getting the following error:
AttributeError: 'Ui_Form' object has no attribute 'lineEdit'
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'PyosUI.ui'
#
# Created by: PyQt5 UI code generator 5.15.7
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import (
QApplication,
QLabel,
QMainWindow,
QPushButton,
QVBoxLayout,
QWidget
)
class GameWindow(QWidget):
def __init__(self):
super.__init__()
layout = QVBoxLayout()
self.label = QLabel("Hello!")
layout.addWidget(self.label)
self.setLayout(layout)
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.setEnabled(True)
Dialog.resize(1044, 601)
self.Notepad = QtWidgets.QPushButton(Dialog)
self.Notepad.setGeometry(QtCore.QRect(50, 520, 281, 61))
self.Notepad.setObjectName("Notepad")
self.Game = QtWidgets.QPushButton(Dialog)
self.Game.setGeometry(QtCore.QRect(390, 520, 271, 61))
self.Game.setObjectName("Game")
self.Poweroff = QtWidgets.QPushButton(Dialog)
self.Poweroff.setGeometry(QtCore.QRect(690, 520, 111, 31))
self.Poweroff.setObjectName("Poweroff")
self.Settings = QtWidgets.QPushButton(Dialog)
self.Settings.setGeometry(QtCore.QRect(690, 560, 111, 31))
self.Settings.setObjectName("Settings")
self.Date_time = QtWidgets.QDateTimeEdit(Dialog)
self.Date_time.setGeometry(QtCore.QRect(840, 20, 194, 22))
self.Date_time.setObjectName("Date_time")
self.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(0, -20, 1051, 641))
self.label.setText("")
self.label.setPixmap(QtGui.QPixmap("background.png"))
self.label.setObjectName("label")
self.label.raise_()
self.Notepad.raise_()
self.Game.raise_()
self.Poweroff.raise_()
self.Settings.raise_()
self.Date_time.raise_()
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
l = QVBoxLayout()
self.Game.clicked.connect(self.button_clicked)
l.addWidget(self.Game)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "PyOS"))
self.Notepad.setText(_translate("Dialog", "Notepad"))
self.Game.setText(_translate("Dialog", "Game"))
self.Poweroff.setText(_translate("Dialog", "Poweroff"))
self.Settings.setText(_translate("Dialog", "Settings"))
def game_window(self):
game_window = QtWidgets.QDialog()
game_window.setWindowTitle("Game")
game_window.resize(600, 600)
game_window.show()
def button_clicked(self):
self.game_window()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
The above code is the UI I made with Pyqt5 designer. For the work I want to make, when the 'Game' button is clicked, a window dedicated to the 'Game' button should appear.
However, when I run the code above, when I press the 'Game' button, a 600 x 600 window appears and then disappears.
Why?
How else can I solve this problem?
Thank you.
The game_window is a local variable within the game_window() method in Ui_Dialog.
Set the window as an instance and it should be fine.
Modified method
# other code remains same.
def game_window(self):
self._game_window = QtWidgets.QDialog()
self._game_window.setWindowTitle("Game")
self._game_window.resize(600, 600)
self._game_window.show()
Edit: The reason to add the underscore (_) is to avoid having the same name as the method name.
I'm using a USB-barcode scanner to set the text of a Qt lineEdit field to scan production order number, My issue is that after scanning the window is closed instead of shifting to next lineEdit_2 to scan item number. How to setup lineEdit to shift the crusor to next lineEdit_2 and be ready for the next scan.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(400, 300)
self.buttonBox = QtWidgets.QDialogButtonBox(Dialog)
self.buttonBox.setGeometry(QtCore.QRect(290, 20, 81, 241))
self.buttonBox.setOrientation(QtCore.Qt.Vertical)
self.buttonBox.setStandardButtons(QtWidgets.QDialogButtonBox.Cancel|QtWidgets.QDialogButtonBox.Ok)
self.buttonBox.setObjectName("buttonBox")
self.lineEdit = QtWidgets.QLineEdit(Dialog)
self.lineEdit.setGeometry(QtCore.QRect(50, 50, 113, 22))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtWidgets.QLineEdit(Dialog)
self.lineEdit_2.setGeometry(QtCore.QRect(50, 120, 113, 22))
self.lineEdit_2.setObjectName("lineEdit_2")
self.lineEdit_3 = QtWidgets.QLineEdit(Dialog)
self.lineEdit_3.setGeometry(QtCore.QRect(50, 200, 113, 22))
self.lineEdit_3.setObjectName("lineEdit_3")
self.retranslateUi(Dialog)
self.buttonBox.accepted.connect(Dialog.accept)
self.buttonBox.rejected.connect(Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
By default the buttons of a QPushButton are pressed when the enter key is clicked and the QDialog has focus, and that click causes the rejected or accepted signal to be emitted, which closes the window, and this is handled by the default and autoDefault properties, so the first thing is to override that behavior.
On the other hand, pressing the enter key does not move to the other QLineEdit, in that case you must listen to that key and use focusNextPrevChild to move the focus.
Finally the codes generated by QtDesigner should not be modified so I will assume that the code you show is in the gui.py file, and I will implement the logic in main.py:
import sys
from PyQt5 import QtCore, QtWidgets
from gui import Ui_Dialog
class Dialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.show()
for btn in self.buttonBox.buttons():
btn.setDefault(False)
btn.setAutoDefault(False)
btn.setFocusPolicy(QtCore.Qt.NoFocus)
def keyPressEvent(self, event):
if event.key() in (QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return):
self.focusNextPrevChild(True)
super().keyPressEvent(event)
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Dialog()
w.show()
sys.exit(app.exec_())
How to fetch the data from Qcalendar. For example, when is select 21/10/2019, "Monday" will be fetched when I click the "ok" button
The following is my code:
from PyQt5 import QtCore, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QCalendarWidget
class Ui_Form(QMainWindow):
def __init__(self):
self.calendarWidget = QtWidgets.QCalendarWidget(Form)
self.label = QtWidgets.QLabel(Form)
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton_2 = QtWidgets.QPushButton(Form)
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(700, 700)
self.calendarWidget.setGeometry(QtCore.QRect(100, 110, 510, 454))
self.calendarWidget.setMinimumSize(QtCore.QSize(200, 144))
self.calendarWidget.setObjectName("calendarWidget")
self.label.setGeometry(QtCore.QRect(100, 50, 101, 31))
self.label.setObjectName("label")
self.pushButton.setGeometry(QtCore.QRect(460, 600, 76, 37))
self.pushButton.setObjectName("backButton")
self.pushButton_2.setGeometry(QtCore.QRect(560, 600, 76, 37))
self.pushButton_2.setObjectName("okbutton")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
selectionMode()
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Select date"))
self.label.setText(_translate("Form", "Select date"))
self.pushButton.setText(_translate("Form", "Back"))
self.pushButton_2.setText(_translate("Form", "ok"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
void QCalendarWidget::clicked(const QDate &date)
This signal is emitted when a mouse button is clicked.
The date the mouse was clicked on is specified by date.
The signal is only emitted when clicked on a valid date, e.g.,
dates are not outside the minimumDate() and maximumDate().
If the selection mode is NoSelection, this signal will not be emitted.
QString QDate::toString(const QString &format) const
Returns the date as a string. The format parameter determines the format of the result string.
https://doc.qt.io/qt-5/qdate.html#toString-2
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMainWindow, QVBoxLayout, QCalendarWidget, QWidget
# WARNING! All changes made in this file will be lost!
class Ui_Form(object):
'''
# WARNING! All changes made in this file will be lost !!!!!!
class Ui_Form(QMainWindow):
def __init__(self):
self.calendarWidget = QtWidgets.QCalendarWidget(Form)
self.label = QtWidgets.QLabel(Form)
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton_2 = QtWidgets.QPushButton(Form)
'''
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(700, 700)
self.calendarWidget = QtWidgets.QCalendarWidget(Form)
self.calendarWidget.setGeometry(QtCore.QRect(100, 110, 510, 454))
self.calendarWidget.setMinimumSize(QtCore.QSize(200, 144))
self.calendarWidget.setObjectName("calendarWidget")
self.label = QtWidgets.QLabel(Form)
self.label.setGeometry(QtCore.QRect(100, 50, 101, 31))
self.label.setObjectName("label")
self.pushButton = QtWidgets.QPushButton(Form)
self.pushButton.setGeometry(QtCore.QRect(460, 600, 76, 37))
self.pushButton.setObjectName("backButton")
self.pushButton_2 = QtWidgets.QPushButton(Form)
self.pushButton_2.setGeometry(QtCore.QRect(560, 600, 76, 37))
self.pushButton_2.setObjectName("okbutton")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
# ? selectionMode()
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Select date"))
self.label.setText(_translate("Form", "Select date"))
self.pushButton.setText(_translate("Form", "Back"))
self.pushButton_2.setText(_translate("Form", "ok"))
class MyWindow(QtWidgets.QWidget, Ui_Form):
def __init__(self):
super(MyWindow, self).__init__()
self.setupUi(self)
self.calendarWidget.setGridVisible(True)
self.calendarWidget.clicked[QtCore.QDate].connect(self.showDate)
self.date = self.calendarWidget.selectedDate()
self.label.setText(self.date.toString("dd-MM-yyyy dddd"))
self.pushButton_2.clicked.connect(self.clickedOk)
def showDate(self, date):
# self.label.setText(date.toString("dd-MM-yyyy dddd")) # ! Try to uncomment !
self.date = date
def clickedOk(self):
self.label.setText(self.date.toString("dd-MM-yyyy dddd"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
# Form = QtWidgets.QWidget()
# ui = Ui_Form()
# ui.setupUi(Form)
# Form.show()
w = MyWindow()
w.show()
sys.exit(app.exec_())
In need a pass a result from an event to QlineEdit box(rs_QLineEdit)
If the event is clicked by passing the Book name it displays book name and price.
There is no problem with database connection as it works well and displays the result in python shell.
I want to pass the price dynamically which is to pass m[2] to rs_QLineEdit
from PyQt5.QtCore import QRegExp
from PyQt5.QtGui import QRegExpValidator
from PyQt5 import QtCore, QtGui, QtWidgets
import sqlite3
def fetch(nm):
store=sqlite3.connect("store.db")
book=store.cursor()
book.execute("select * from books where title='"+nm+"';")
m=book.fetchone()
if m==None:
print("Book is not Found")
else:
print("the name is {} ".format(nm)) #The Wings of Fire
print(m[2]) #200
store.close()
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(635, 510)
self.find = QtWidgets.QPushButton(Form)
self.find.setGeometry(QtCore.QRect(370, 200, 93, 28))
self.find.setObjectName("find_button")
self.find.setToolTip("Press this")
self.name = QtWidgets.QLabel(Form)
self.name.setGeometry(QtCore.QRect(100, 200, 55, 16))
self.name.setObjectName("name_label")
self.price = QtWidgets.QLabel(Form)
self.price.setGeometry(QtCore.QRect(100, 260, 55, 16))
self.price.setObjectName("price_label")
self.rs = QtWidgets.QLineEdit(Form)
self.rs.setGeometry(QtCore.QRect(230, 260, 55, 16))
self.rs.setObjectName("rs_QLineEdit")
self.lineEdit = QtWidgets.QLineEdit(Form)
self.lineEdit.setGeometry(QtCore.QRect(220, 200, 113, 22))
self.lineEdit.setObjectName("lineEdit")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
self.find.clicked.connect(lambda : fetch(str(self.lineEdit.text())))
reg_ex = QRegExp("[0-9]+.?[0-9]{,2}")
input_validator = QRegExpValidator(reg_ex, self.rs)
self.rs.setValidator(input_validator)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.find.setText(_translate("Form", "Find"))
self.name.setText(_translate("Form", "Name"))
self.price.setText(_translate("Form", "Price"))
self.rs.setText(_translate("Form", "RS."))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Form = QtWidgets.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
Although lambda methods are useful for certain types of tasks in general you should not abuse them because they have many limitations, in your case the fetch function should return the result but within a lambda method it is difficult to establish (it can be in theory but it would be unreadable).
In addition to this I take the trouble to improve your code following the recommendations of PyQt: http://pyqt.sourceforge.net/Docs/PyQt5/designer.html#using-the-generated-code, in it I recommend not to modify the class generated by Qt Designer but to implement another class that inherits from the widget and use the initial class to fill in the widget, in that new class the logic is implemented.
Code:
import sqlite3
from PyQt5 import QtCore, QtGui, QtWidgets
def fetch(nm):
store=sqlite3.connect("store.db")
book=store.cursor()
book.execute("select * from books where title='{}';".format(nm))
m=book.fetchone()
store.close()
if m:
print("the name is {} ".format(nm))
return m[2]
else:
print("Book is not Found")
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(635, 510)
self.find = QtWidgets.QPushButton(Form)
self.find.setGeometry(QtCore.QRect(370, 200, 93, 28))
self.find.setObjectName("find_button")
self.find.setToolTip("Press this")
self.name = QtWidgets.QLabel(Form)
self.name.setGeometry(QtCore.QRect(100, 200, 55, 16))
self.name.setObjectName("name_label")
self.price = QtWidgets.QLabel(Form)
self.price.setGeometry(QtCore.QRect(100, 260, 55, 16))
self.price.setObjectName("price_label")
self.rs = QtWidgets.QLineEdit(Form)
self.rs.setGeometry(QtCore.QRect(230, 260, 55, 16))
self.rs.setObjectName("rs_QLineEdit")
self.lineEdit = QtWidgets.QLineEdit(Form)
self.lineEdit.setGeometry(QtCore.QRect(220, 200, 113, 22))
self.lineEdit.setObjectName("lineEdit")
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
self.find.setText(_translate("Form", "Find"))
self.name.setText(_translate("Form", "Name"))
self.price.setText(_translate("Form", "Price"))
self.rs.setText(_translate("Form", "RS."))
class Widget(QtWidgets.QWidget, Ui_Form):
def __init__(self, parent=None):
QtWidgets.QWidget.__init__(self, parent)
self.setupUi(self)
self.find.clicked.connect(self.onFindClicked)
reg_ex = QtCore.QRegExp("[0-9]+.?[0-9]{,2}")
input_validator = QtGui.QRegExpValidator(reg_ex, self.rs)
self.rs.setValidator(input_validator)
#QtCore.pyqtSlot()
def onFindClicked(self):
title = self.lineEdit.text()
name = fetch(title)
if name:
self.rs.setText(str(name))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
The accepted answer is fine, but I don't necessarily agree about avoiding lambda functions. They are super useful when programming in PyQt. As per the docs for QPushButton's super class QAbstractButton, clicked takes one argument, bool checked = false. It's actually pretty useless on QPushButton as far as I've seen, but nevertheless, your lambda has to account for any arguments. Change your connect line to
self.find.clicked.connect(lambda c: fetch(str(self.lineEdit.text())))
# ^ This is the important part