I am grabbing the user input from the line edit and displaying it on the QMessageBox but it won't show for some reason. I thought maybe I wasn't grabbing the input from QLineEdit at all but when I tried printing it on the terminal (it still wouldn't show there btw) the terminal scrolled down, recognizing that there is new data in it but just not displaying it. Get what I am saying?
import os
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
def main():
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
# create objects
label = QLabel(self.tr("enter the data "))
self.le = QLineEdit()
self.te = QTextEdit()
# layout
layout = QVBoxLayout(self)
layout.addWidget(label)
layout.addWidget(self.le)
layout.addWidget(self.te)
self.setLayout(layout)
# create connection
self.mytext = str(self.le.text())
self.connect(self.le, SIGNAL("returnPressed(void)"),
self.display)
def display(self):
QApplication.instance().processEvents()
msg = QMessageBox.about(self, 'msg', '%s' % self.mytext)
print(self.mytext)
self.te.append(self.mytext)
self.le.setText("")
if __name__ == "__main__":
main()
You are currently reading the QLineEdit in the constructor, and at that moment the QLineEdit is empty, you must do it in the slot:
def display(self):
mytext = self.le.text()
msg = QMessageBox.about(self, 'msg', '%s' % mytext)
self.te.append(mytext)
self.le.clear()
Note: use clear() to clean the QLineEdit
Related
Summary:
I've been using QMessageBox in my application (for this purpose asking for saving project before closing, Error messages), And now I want to have a custom style (Custom title bar, custom buttons and so on), I found it is hard to do that with QMessageBox, And since I've been using a QDialog in my application as well (For this purpose: Taking input from user), I decided to use a custom QDialog (Make my own style on it) instead of QMessageBox for these all previous purpose, since it is easier to customize and creating my style.
The problem:
The problem that I have now is: QDialog return only a flag value (0,1) depending on the button role And that's fine if I have only 2 buttons BUT here I have 3 (Save, Cancel, Close), Save will return 1 and both Close and Cancel return 0. And QMessageBox as I've seen it return the id of the Button that was clicked.
An example (commented well hopefully :D):
from PyQt5.QtWidgets import *
class CustomDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Data will be lost")
label = QLabel("Are you sure you want close the app before saving?")
buttonBox = QDialogButtonBox()
buttonBox.addButton(QDialogButtonBox.Save)
buttonBox.addButton(QDialogButtonBox.Cancel)
buttonBox.addButton(QDialogButtonBox.Close)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(buttonBox)
self.resize(300, 100)
self.setLayout(layout)
# These two lines, return 0 or 1.
buttonBox.rejected.connect(self.reject)
buttonBox.accepted.connect(self.accept)
class Window(QWidget):
def __init__(self):
super().__init__()
label = QLabel('Hello Dialog', self)
open_dialog_button = QPushButton('Open Dialog', self)
open_dialog_button.clicked.connect(self.showDialog)
open_message_box_button = QPushButton('Open Message Box', self)
open_message_box_button.clicked.connect(self.show_message_box)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(open_dialog_button)
layout.addWidget(open_message_box_button)
self.setLayout(layout)
def showDialog(self):
self.dialog = CustomDialog(self)
btn_clicked = self.dialog.exec_() # dialog exec returns 0 or 1 (Save = 1, Close and Cancel returns 0)
# I want something like this.
if btn_clicked == QDialogButtonBox.Save:
print("Close.. After Saving...")
elif btn_clicked == QDialogButtonBox.Close:
print("Close.. Without saving")
else:
print("Cancel.. Don't exit the program")
def show_message_box(self):
msg = QMessageBox()
msg.setIcon(QMessageBox.Warning)
msg.setText("Are you sure you want close the app before saving?")
msg.setStandardButtons(QMessageBox.Close | QMessageBox.Save | QMessageBox.Cancel)
msg.setWindowTitle("Data will be lost")
btn_clicked = msg.exec_()
# Here i can do this.
if btn_clicked == QMessageBox.Save:
print("Close.. After Saving...")
elif btn_clicked == QMessageBox.Close:
print("Close.. Without saving")
else:
print("Cancel.. Don't exit the program")
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
win = Window()
win.resize(200, 200)
win.show()
sys.exit(app.exec_())
I've found the solution and it worked with me by using a custom signal and slot, but still not sure if it is good or not. waiting for approval and then I can mark this solution as an accepted one.
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class CustomDialog(QDialog):
# Create a signal
signal = pyqtSignal(int)
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Data will be lost")
label = QLabel("Are you sure you want close the app before saving?")
self.buttonBox = QDialogButtonBox()
self.buttonBox.addButton(QDialogButtonBox.Save)
self.buttonBox.addButton(QDialogButtonBox.Cancel)
self.buttonBox.addButton(QDialogButtonBox.Close)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(self.buttonBox)
self.resize(300, 100)
self.setLayout(layout)
# connect each button with custom slot
self.buttonBox.button(QDialogButtonBox.Save).clicked.connect(lambda: self.customSlot(QDialogButtonBox.Save))
self.buttonBox.button(QDialogButtonBox.Close).clicked.connect(lambda: self.customSlot(QDialogButtonBox.Close))
self.buttonBox.button(QDialogButtonBox.Cancel).clicked.connect(lambda: self.customSlot(QDialogButtonBox.Cancel))
# connect signal with buil-in function from QDialog (done())
# This done function will return <int> value and close the dialog.
self.signal.connect(self.done)
def customSlot(self, button_id):
# emit button's id
self.signal.emit(button_id)
class Window(QWidget):
def __init__(self):
super().__init__()
label = QLabel('Hello Dialog', self)
open_dialog_button = QPushButton('Open Dialog', self)
open_dialog_button.clicked.connect(self.showDialog)
layout = QVBoxLayout()
layout.addWidget(label)
layout.addWidget(open_dialog_button)
self.setLayout(layout)
def showDialog(self):
dialog = CustomDialog()
btn_clicked = dialog.exec_() # dialog exec returns button's id
# Now you can use the following lines of code
if btn_clicked == QDialogButtonBox.Save:
print("Close.. After Saving...")
elif btn_clicked == QDialogButtonBox.Close:
print("Close.. Without saving")
else:
print("Cancel.. Don't exit the program")
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
win = Window()
win.resize(200, 200)
win.show()
sys.exit(app.exec_())
I am using QFileDialog.getOpenFileName(self,'Remove File', "path", '*.pdf') to select a file and get the path in order to remove it from my application. The issue is the QFileDialog.getOpenFileName window button says 'Open' when selecting a file which will be confusing to the user.
Is there any way to change the button text from 'Open' to 'Remove'/'Delete'
When using the static method QFileDialog::getOpenFileName() the first thing is to obtain the QFileDialog object and for that we use a QTimer and the findChild() method:
# ...
QtCore.QTimer.singleShot(0, self.on_timeout)
filename, _ = QtWidgets.QFileDialog.getOpenFileName(...,
options=QtWidgets.QFileDialog.DontUseNativeDialog)
def on_timeout(self):
dialog = self.findChild(QtWidgets.QFileDialog)
# ...
Then you can get the text iterating over the buttons until you get the button with the searched text and change it:
for btn in dialog.findChildren(QtWidgets.QPushButton):
if btn.text() == "&Open":
btn.setText("Remove")
That will work at the beginning but every time you interact with the QTreeView they show, update the text to the default value, so the same logic will have to be applied using the currentChanged signal from the selectionModel() of the QTreeView but for synchronization reasons it is necessary Update the text later using another QTimer.singleShot(), the following code is a workable example:
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Press me")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
#QtCore.pyqtSlot()
def on_clicked(self):
QtCore.QTimer.singleShot(0, self.on_timeout)
filename, _ = QtWidgets.QFileDialog.getOpenFileName(
self,
"Remove File",
"path",
"*.pdf",
options=QtWidgets.QFileDialog.DontUseNativeDialog,
)
def on_timeout(self):
dialog = self.findChild(QtWidgets.QFileDialog)
dialog.findChild(QtWidgets.QTreeView).selectionModel().currentChanged.connect(
lambda: self.change_button_name(dialog)
)
self.change_button_name(dialog)
def change_button_name(self, dialog):
for btn in dialog.findChildren(QtWidgets.QPushButton):
if btn.text() == self.tr("&Open"):
QtCore.QTimer.singleShot(0, lambda btn=btn: btn.setText("Remove"))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
The first step can be avoided if the static method is not used and create the dialog using an instance of QFileDialog:
import sys
from PyQt5 import QtCore, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
button = QtWidgets.QPushButton("Press me")
button.clicked.connect(self.on_clicked)
lay = QtWidgets.QVBoxLayout(self)
lay.addWidget(button)
#QtCore.pyqtSlot()
def on_clicked(self):
dialog = QtWidgets.QFileDialog(
self,
"Remove File",
"path",
"*.pdf",
supportedSchemes=["file"],
options=QtWidgets.QFileDialog.DontUseNativeDialog,
)
self.change_button_name(dialog)
dialog.findChild(QtWidgets.QTreeView).selectionModel().currentChanged.connect(
lambda: self.change_button_name(dialog)
)
if dialog.exec_() == QtWidgets.QDialog.Accepted:
filename = dialog.selectedUrls()[0]
print(filename)
def change_button_name(self, dialog):
for btn in dialog.findChildren(QtWidgets.QPushButton):
if btn.text() == self.tr("&Open"):
QtCore.QTimer.singleShot(0, lambda btn=btn: btn.setText("Remove"))
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
While I appreciate the solution provided by #eyllanesc, I'd like to propose a variation.
Under certain circumstances, the code for that answer might fail, specifically:
the delay that X11 suffers from mapping windows;
the checking of localized button strings;
the selection using the file name edit box;
Considering the above, I propose an alternate solution, based on the points above.
For obvious reasons, the main point remains: the dialog must be non-native.
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class FileDialogTest(QWidget):
def __init__(self):
super().__init__()
layout = QHBoxLayout(self)
self.fileEdit = QLineEdit()
layout.addWidget(self.fileEdit)
self.selectBtn = QToolButton(icon=QIcon.fromTheme('folder'), text='…')
layout.addWidget(self.selectBtn)
self.selectBtn.clicked.connect(self.showSelectDialog)
def checkSelectDialog(self):
dialog = self.findChild(QFileDialog)
if not dialog.isVisible():
# wait for dialog finalization, as testOption might fail
return
# dialog found, stop the timer and delete it
self.sender().stop()
self.sender().deleteLater()
if not dialog.testOption(dialog.DontUseNativeDialog):
# native dialog, we cannot do anything!
return
def updateOpenButton():
selection = tree.selectionModel().selectedIndexes()
if selection and not tree.model().isDir(selection[0]):
# it's a file, change the button text
button.setText('Select my precious file')
tree = dialog.findChild(QTreeView)
button = dialog.findChild(QDialogButtonBox).button(
QDialogButtonBox.Open)
# check for selected files on open
updateOpenButton()
# connect the selection update signal
tree.selectionModel().selectionChanged.connect(
lambda: QTimer.singleShot(0, updateOpenButton))
def showSelectDialog(self):
QTimer(self, interval=10, timeout=self.checkSelectDialog).start()
path, filter = QFileDialog.getOpenFileName(self,
'Select file', '<path_to_file>',
"All Files (*);;Python Files (*.py);; PNG Files (*.png)",
options=QFileDialog.DontUseNativeDialog)
if path:
self.fileEdit.setText(path)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
ex = FileDialogTest()
ex.show()
sys.exit(app.exec())
Obviously, for PyQt6 you'll need to use the proper Enum namespaces (i.e. QFileDialog.Option.DontUseNativeDialog, etc.).
I read this: How to resize QInputDialog, PyQt but it didnt work for me, as it seems to be about PyQt4
This is my code snipplet:
def ImportURL(self): #URL dialog aufrufen
InputDialog = QtWidgets.QInputDialog(self)
i, okPressed = InputDialog.getText(self, "Import website", "Site to import:", QtWidgets.QLineEdit.Normal, "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite")
if okPressed:
self.getWebsite(i)
And i tried adding .setFixedSize in the 2nd line. I tried adding InputDialog.setFixedSite(self) between line 2 and 3. Nothing worked, it either crashes or it creates a second, empty window. Am i overlooking something here?
In the answers to the other question do not explain the cause of the problem so in my answer will try to cover as much as possible
Explanation:
The getText() method is a static method, which means that an object is not used, in the method internally if it is used but it is not accessible. So the InputDialog that you create is not the one you show and this you can check using the following code since you will see 2 windows:
def ImportURL(self):
InputDialog = QtWidgets.QInputDialog(self)
InputDialog.show()
i, okPressed = InputDialog.getText(self, "Import website", "Site to import:", QtWidgets.QLineEdit.Normal, "https://de.wikipedia.org/wiki/Wikipedia:Hauptseite")
if okPressed:
self.getWebsite(i)
Solutions:
So there are the following solutions:
Taking advantage of what you have passed as a parent to self, you can obtain the object using findChildren:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
button = QtWidgets.QPushButton(
"Open QInputDialog", clicked=self.ImportURL
)
vlay = QtWidgets.QVBoxLayout(self)
vlay.addWidget(button)
#QtCore.pyqtSlot()
def ImportURL(self):
QtCore.QTimer.singleShot(0, self.after_show)
i, okPressed = QtWidgets.QInputDialog.getText(
self,
"Import website",
"Site to import:",
QtWidgets.QLineEdit.Normal,
"https://de.wikipedia.org/wiki/Wikipedia:Hauptseite",
)
if okPressed:
# self.getWebsite(i)
print(i)
#QtCore.pyqtSlot()
def after_show(self):
size = QtCore.QSize(500, 100)
for d in self.findChildren(QtWidgets.QInputDialog):
if d.isVisible():
d.resize(size)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Do not use the getText() method but create an object that implements the same logic:
from PyQt5 import QtCore, QtGui, QtWidgets
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Widget, self).__init__(parent)
button = QtWidgets.QPushButton(
"Open QInputDialog", clicked=self.ImportURL
)
vlay = QtWidgets.QVBoxLayout(self)
vlay.addWidget(button)
#QtCore.pyqtSlot()
def ImportURL(self):
dialog = QtWidgets.QInputDialog(self)
dialog.resize(QtCore.QSize(500, 100))
dialog.setWindowTitle("Import website")
dialog.setLabelText("Site to Import")
dialog.setTextValue(
"https://de.wikipedia.org/wiki/Wikipedia:Hauptseite"
)
dialog.setTextEchoMode(QtWidgets.QLineEdit.Normal)
if dialog.exec_() == QtWidgets.QDialog.Accepted:
i = dialog.textValue()
print(i)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())
Update:
The layout of the QInputDialog has QLayout::SetMinAndMaxSize set as sizeConstraint, so the fixed size will not work, the trick is to change it to QLayout::SetDefaultConstraint:
from functools import partial
# ...
#QtCore.pyqtSlot()
def ImportURL(self):
dialog = QtWidgets.QInputDialog(self)
dialog.setWindowTitle("Import website")
dialog.setLabelText("Site to Import")
dialog.setTextValue(
"https://de.wikipedia.org/wiki/Wikipedia:Hauptseite"
)
dialog.setTextEchoMode(QtWidgets.QLineEdit.Normal)
wrapper = partial(self.on_timeout, dialog)
QtCore.QTimer.singleShot(0, wrapper)
if dialog.exec_() == QtWidgets.QDialog.Accepted:
i = dialog.textValue()
print(i)
def on_timeout(self, dialog):
lay = dialog.layout()
lay.setSizeConstraint(QtWidgets.QLayout.SetDefaultConstraint)
dialog.setFixedSize(QtCore.QSize(500, 100))
I have the following window with frames.
I want frame to be highlighted (in my case change its shape) when mouse is in its area.
from PyQt4 import QtGui, QtCore
import sys
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
window_layout = QtGui.QVBoxLayout()
window.setLayout(window_layout)
#fill content
for i in range(10):
label = QtGui.QLabel(str(i))
frame = QtGui.QFrame()
frame_layout = QtGui.QVBoxLayout()
frame.setLayout(frame_layout)
frame_layout.addWidget(label)
window_layout.addWidget(frame)
def layout_widgets(layout):
return (layout.itemAt(i) for i in range(layout.count()))
def mouse_enter(event):
print 'frame enter'
w.widget().setFrameShape(3)
def mouse_leave(event):
print 'frame leave'
w.widget().setFrameShape(0)
for w in layout_widgets(window_layout):
print w.widget()
w.widget().enterEvent = mouse_enter
w.widget().leaveEvent = mouse_leave
window.show()
sys.exit(app.exec_())
It works but only the last frame in layout highlights.
How to make only that frame change its shape where the mouse is?
I've tried the following:
def mouse_enter(event, frame):
print 'frame enter'
frame.setFrameShape(3)
w.widget().enterEvent = functools.partial(mouse_enter, w.widget())
but it gives an error. I have found one more way to do that - signal mapper
but I have no idea how to use it.
The problem in your code the variable w when executing the for is left with the last element, so it will only be executed in the latter. To solve this I have implemented a Frame class that inherits from QFrame where I overwrite the enterEvent and leaveEvent functions.
from PyQt4 import QtGui, QtCore
import sys
class Frame(QtGui.QFrame):
def __init__(self, text, parent=None):
super(Frame, self).__init__(parent=parent)
label = QtGui.QLabel(text)
frame_layout = QtGui.QVBoxLayout()
frame_layout.addWidget(label)
self.setLayout(frame_layout)
def enterEvent(self, event):
self.setFrameShape(3)
def leaveEvent(self, event):
self.setFrameShape(0)
app = QtGui.QApplication(sys.argv)
window = QtGui.QWidget()
window_layout = QtGui.QVBoxLayout()
window.setLayout(window_layout)
for i in range(10):
frame = Frame(str(i))
window_layout.addWidget(frame)
window.show()
sys.exit(app.exec_())
I am developing an application using python and Qt.
I have designed 2 Main windows ie..QMainWindow (Not QWidget or QDialog) using Qt.
Let it be.
1.LoginWindow -- LoginUI(Qt)
2.StuffWindow --- StuffUI
First i should display Login Window.
Then i should pass the username to StaffWindow (username needed for managing stuffs)
StaffWindow should be shown and LoginWindow Should be Closed..
How can i achieve this..? Help me..
Regardless of your description, I think your LoginWindow should be a QDialog, and your StuffWIndow be the MainWindow, and function like this...
Your StuffWindow MainWindow should be created (not shown)
Call a login() method that creates and exec_() your login QDialog as a application MODAL dialog
Start the app.exec_() event loop now, and wait for the user to interact with login
User interacts with login dialog, and the result of the dialog closing will then allow your app to check its values and choose to show its main interface.
Here is a quick outline:
class MainWindow():
def login():
loginDialog = LoginDialog()
# this is modal. wait for it to close
if loginDialog.exec_():
# dialog was accepted. check its values and maybe:
self.show()
else:
# maybe reshow the login dialog if they rejected it?
loginDialog.exec_()
if __name__ == "__main__":
app = QApp
win = MainWindow()
win.login()
app.exec_()
I do agree most of the points jdi raised, but I prefer a slightly different approach.
LoginWindow should be a QDialog started as MODAL.
Check the return of exec_() (i.e. accept/reject) for login or cancel/quit.
Check the login inside the LoginWindow
If successful login, launch MainWindow with parameters supplied
I started coding a simple example before seeing jdi's answer. I might as well put it here.
import sys
from PyQt4 import QtGui, QtCore
class LoginDialog(QtGui.QDialog):
def __init__(self, parent=None):
super(LoginDialog, self).__init__(parent)
self.username = QtGui.QLineEdit()
self.password = QtGui.QLineEdit()
loginLayout = QtGui.QFormLayout()
loginLayout.addRow("Username", self.username)
loginLayout.addRow("Password", self.password)
self.buttons = QtGui.QDialogButtonBox(QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel)
self.buttons.accepted.connect(self.check)
self.buttons.rejected.connect(self.reject)
layout = QtGui.QVBoxLayout()
layout.addLayout(loginLayout)
layout.addWidget(self.buttons)
self.setLayout(layout)
def check(self):
if str(self.password.text()) == "12345": # do actual login check
self.accept()
else:
pass # or inform the user about bad username/password
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.label = QtGui.QLabel()
self.setCentralWidget(self.label)
def setUsername(self, username):
# do whatever you want with the username
self.username = username
self.label.setText("Username entered: %s" % self.username)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
login = LoginDialog()
if not login.exec_(): # 'reject': user pressed 'Cancel', so quit
sys.exit(-1)
# 'accept': continue
main = MainWindow()
main.setUsername(login.username.text()) # get the username, and supply it to main window
main.show()
sys.exit(app.exec_())
Although this is not directly relevant to your question, you should always set QLineEdit.EchoMode for the password field as follows (see here):
self.password.setEchoMode(QtGui.QLineEdit.Password)
This is PyQt5 updated version of Avaris. Some exception handling was added to show how to catch a few errors (while coding your thing. Enjoy!
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Ref to this OP question. https://stackoverflow.com/questions/9689053/how-to-communicate-or-switch-between-two-windows-in-pyqt4
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox, QFormLayout, QLabel, QLineEdit, QWidget, QVBoxLayout
class LoginDialog(QtWidgets.QDialog):
def __init__(self, parent=None):
super(LoginDialog, self).__init__(parent)
self.username = QLineEdit()
self.password = QLineEdit()
loginLayout = QFormLayout()
loginLayout.addRow("Username", self.username)
loginLayout.addRow("Password", self.password)
self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttons.accepted.connect(self.check)
self.buttons.rejected.connect(self.reject)
layout = QVBoxLayout()
layout.addLayout(loginLayout)
layout.addWidget(self.buttons)
self.setLayout(layout)
def check(self):
if str(self.password.text()) == "12345": # do actual login check
self.accept()
else:
pass # or inform the user about bad username/password
def my_exception_hook(exctype, value, traceback):
# Print the error and traceback
print(exctype, value, traceback)
# Call the normal Exception hook after
sys._excepthook(exctype, value, traceback)
sys.exit(1)
# Back up the reference to the exceptionhook
sys._excepthook = sys.excepthook
# Set the exception hook to our wrapping function
sys.excepthook = my_exception_hook
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.label = QLabel()
self.setCentralWidget(self.label)
def setUsername(self, username):
# do whatever you want with the username
self.username = username
self.label.setText("Username entered: %s" % self.username)
if __name__ == "__main__":
app = QApplication(sys.argv)
login = LoginDialog()
if not login.exec_(): # 'reject': user pressed 'Cancel', so quit
sys.exit(-1) # instead of -1 another action can be triggered here.
# 'accept': continue
main = MainWindow()
# get the username, and supply it to main window
main.setUsername(login.username.text())
main.show()
sys.exit(app.exec_())
to match username and password.
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
from PyQt5.QtWidgets import QApplication, QDialog, QDialogButtonBox, QFormLayout, QLabel, QLineEdit, QWidget, QVBoxLayout, QMessageBox
class LoginDialog(QtWidgets.QDialog):
def __init__(self, parent=None):
super(LoginDialog, self).__init__(parent)
self.username = QLineEdit()
self.password = QLineEdit()
loginLayout = QFormLayout()
loginLayout.addRow("Username", self.username)
loginLayout.addRow("Password", self.password)
self.buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.buttons.accepted.connect(self.check)
self.buttons.rejected.connect(self.reject)
layout = QVBoxLayout()
layout.addLayout(loginLayout)
layout.addWidget(self.buttons)
self.setLayout(layout)
def check(self):
if str(self.username.text()) == "foo" and str(self.password.text()) == "bar": # do actual login check
self.accept()
else:
QMessageBox.warning(
self, 'Error', 'Bad user or password')
pass # or inform the user about bad username/password
def my_exception_hook(exctype, value, traceback):
# Print the error and traceback
print(exctype, value, traceback)
# Call the normal Exception hook after
sys._excepthook(exctype, value, traceback)
sys.exit(1)
# Back up the reference to the exceptionhook
sys._excepthook = sys.excepthook
# Set the exception hook to our wrapping function
sys.excepthook = my_exception_hook
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.label = QLabel()
self.setCentralWidget(self.label)
def setUsername(self, username):
# do whatever you want with the username
self.username = username
self.label.setText("%s%s%s" % ("Username entered: ", self.username, "\npassword ok!"))
if __name__ == "__main__":
app = QApplication(sys.argv)
login = LoginDialog()
if not login.exec_(): # 'reject': user pressed 'Cancel', so quit
sys.exit(-1) # instead of -1 another action can be triggered here.
# 'accept': continue
main = MainWindow()
# get the username, and supply it to main window
main.setUsername(login.username.text())
main.show()
sys.exit(app.exec_())