set strings to comboBox from other Dialog - python

I have made two GUIs in Pyqt5 & Qt Designer. The first GUI is to show the person name in a comboBox. The second GUI will be opend by clicking + button and then the user can write the name,age and job which i need later in other thing.
My Question is, how can i get the new name from the 2. GUI and set it in comboBox of the 1. GUI. I tried that in the below code but it doesn't work.
whole code:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import *
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(363, 165)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(30, 30, 68, 19))
self.label.setObjectName("label")
self.comboBox = QtWidgets.QComboBox(self.centralwidget)
self.comboBox.setGeometry(QtCore.QRect(120, 30, 131, 25))
self.comboBox.setObjectName("comboBox")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(280, 30, 41, 34))
self.pushButton.setObjectName("pushButton")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 363, 31))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "person"))
self.pushButton.setText(_translate("MainWindow", "+"))
def InputDialog1(self):
self.Dialog = QtWidgets.QDialog()
self.ui=Ui_Dialog()
self.ui.setupUi(self.Dialog)
self.Dialog.setWindowTitle('Add Infos')
self.Dialog.show()
class Person_data(object):
def __init__(self,parent=None):
self.Person_1 = {'-':[0,0]}
class MainWindow(QMainWindow, Ui_MainWindow,Person_data):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent=parent)
Person_data.__init__(self, parent=parent)
self.setupUi(self)
self.initMe()
def initMe(self):
self.pushButton.clicked.connect(self.InputDialog1)
Person_list={}
for i in self.Person_1.keys():
Person_list[i] = ''
Person_list_2 = list(Person_list)
print(Person_list_2)
self.comboBox.addItems(Person_list_2)
class Ui_Dialog(Person_data):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(344, 231)
self.pushButton = QtWidgets.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(170, 160, 112, 34))
self.pushButton.setObjectName("pushButton")
self.pushButton_2 = QtWidgets.QPushButton(Dialog)
self.pushButton_2.setGeometry(QtCore.QRect(30, 160, 112, 34))
self.pushButton_2.setObjectName("pushButton_2")
self.gridLayoutWidget = QtWidgets.QWidget(Dialog)
self.gridLayoutWidget.setGeometry(QtCore.QRect(30, 20, 271, 121))
self.gridLayoutWidget.setObjectName("gridLayoutWidget")
self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
self.gridLayout.setContentsMargins(0, 0, 0, 0)
self.gridLayout.setObjectName("gridLayout")
self.lineEdit_2 = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.lineEdit_2.setObjectName("lineEdit_2")
self.gridLayout.addWidget(self.lineEdit_2, 1, 1, 1, 1)
self.lineEdit = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.lineEdit.setObjectName("lineEdit")
self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
self.lineEdit_3 = QtWidgets.QLineEdit(self.gridLayoutWidget)
self.lineEdit_3.setObjectName("lineEdit_3")
self.gridLayout.addWidget(self.lineEdit_3, 2, 1, 1, 1)
self.label_2 = QtWidgets.QLabel(self.gridLayoutWidget)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
self.label_3 = QtWidgets.QLabel(self.gridLayoutWidget)
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
self.label = QtWidgets.QLabel(self.gridLayoutWidget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
self.pushButton.clicked.connect(self.okpress)
self.pushButton_2.clicked.connect(Dialog.close)
def okpress(self):
aa1=float(self.lineEdit_2.text());aa2=float(self.lineEdit_3.text())
self.Person_1[str(self.lineEdit.text())] = [aa1,aa2]
i = True
while i == True:
bb = MainWindow()
Person_list={}
for i in self.Person_1.keys():
Person_list[i] = ''
Person_list_2 = list(Person_list)
print(Person_list_2)
bb.comboBox.addItems(Person_list_2)
i=False #just to exit while
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.pushButton.setText(_translate("Dialog", "add"))
self.pushButton_2.setText(_translate("Dialog", "Cancel"))
self.label_2.setText(_translate("Dialog", "Age"))
self.label_3.setText(_translate("Dialog", "Job"))
self.label.setText(_translate("Dialog", "Name"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.setWindowTitle('Main Person Windows')
w.show()
sys.exit(app.exec_())

It is not recommended that you modify the code generated by Qt Designer, since you can have unexpected behaviors, in addition to messing up the code. The appropriate thing from my perspective is to create classes that inherit from the appropriate widgets and that use the design of QtDesigner, so my answer includes the restructuring of the code to make it more readable.
Analyzing in your code I see that you confuse the inheritance with the idea of sharing data, when it is inherited from a class it creates similar but not equal elements in each class, even though each object of those classes create similar objects among them but they are not the same , are not the same variables so they point to different memory space, in your case you think that as Ui_Dialog and MainWindow inherit from Person_data, then the variables Person_1 in both classes are the same, and in reality it is not.
Another problem that your code has is the validation, one must try that the user places appropriate values and must interact with certain elements when necessary, for example the conversion to float can cause problems if the text is empty or is not a number, also the add button should only be enabled if all fields are filled in properly, for this Qt provides classes such as QIntValidator.
QDialog is a class specialized in forms and we should try as much as possible to use exec_() since it returns if the form is accepted or not, but for this you must use the accept and reject methods when the buttons are appropriate.
Code:
class PersonDialog(QtWidgets.QDialog, Ui_Dialog):
def __init__(self, *args, **kwargs):
QtWidgets.QDialog.__init__(self, *args, **kwargs)
self.setupUi(self)
self.pushButton.clicked.connect(self.accept)
self.pushButton_2.clicked.connect(self.reject)
self.lineEdit_3.setValidator(QtGui.QIntValidator(0, 100))
self.lineEdit.textChanged.connect(self.enableButtonAccept)
self.lineEdit_2.textChanged.connect(self.enableButtonAccept)
self.lineEdit_3.textChanged.connect(self.enableButtonAccept)
self.enableButtonAccept()
def enableButtonAccept(self):
if self.lineEdit.text() != "" and self.lineEdit_2.text() != "" and self.lineEdit_3.text() != "":
self.pushButton.setEnabled(True)
else:
self.pushButton.setEnabled(False)
def getPerson(self):
values = self.lineEdit.text(), self.lineEdit_2.text(), int(self.lineEdit_3.text())
self.lineEdit.clear()
self.lineEdit_2.clear()
self.lineEdit_3.clear()
return values
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
self.Person_1 = {}
self.initMe()
def initMe(self):
self.personDialog = PersonDialog(self)
self.pushButton.clicked.connect(self.InputDialog1)
def InputDialog1(self):
if self.personDialog.exec_() == PersonDialog.Accepted:
name, job, edad = self.personDialog.getPerson()
self.Person_1[name] = [job, edad]
self.comboBox.addItem(name)

Related

How to get the widget that has the focus

As in the title, I need to get child's name. However, the template is from Qt Creator and all objects are created in the program. I don't know how to subclass them (as I shoudn't change generated file), so all objects after calling would return self.sender(). Is there any other way?
Edit:
I'm giving mre code to reproduce the problem. Here is generated file:
from PyQt5 import QtCore, QtGui, QtWidgets
class UiBazaDanych(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(400, 300)
self.centralWidget = QtWidgets.QWidget(MainWindow)
self.centralWidget.setObjectName("centralWidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralWidget)
self.gridLayout.setContentsMargins(11, 11, 11, 11)
self.gridLayout.setSpacing(6)
self.gridLayout.setObjectName("gridLayout")
self.comboBox = QtWidgets.QComboBox(self.centralWidget)
self.comboBox.setObjectName("comboBox")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.comboBox.addItem("")
self.gridLayout.addWidget(self.comboBox, 0, 2, 1, 1)
self.lineEdit = QtWidgets.QLineEdit(self.centralWidget)
self.lineEdit.setObjectName("lineEdit")
self.gridLayout.addWidget(self.lineEdit, 1, 0, 1, 1)
self.dateEdit = QtWidgets.QDateEdit(self.centralWidget)
self.dateEdit.setObjectName("dateEdit")
self.gridLayout.addWidget(self.dateEdit, 1, 2, 1, 1)
self.label_2 = QtWidgets.QLabel(self.centralWidget)
self.label_2.setObjectName("label_2")
self.gridLayout.addWidget(self.label_2, 1, 1, 1, 1)
self.label = QtWidgets.QLabel(self.centralWidget)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.pushButton = QtWidgets.QPushButton(self.centralWidget)
self.pushButton.setObjectName("pushButton")
self.gridLayout.addWidget(self.pushButton, 2, 2, 1, 1)
self.doubleSpinBox = QtWidgets.QDoubleSpinBox(self.centralWidget)
self.doubleSpinBox.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
self.doubleSpinBox.setObjectName("doubleSpinBox")
self.gridLayout.addWidget(self.doubleSpinBox, 2, 0, 1, 1)
MainWindow.setCentralWidget(self.centralWidget)
self.menuBar = QtWidgets.QMenuBar(MainWindow)
self.menuBar.setGeometry(QtCore.QRect(0, 0, 400, 21))
self.menuBar.setObjectName("menuBar")
MainWindow.setMenuBar(self.menuBar)
self.mainToolBar = QtWidgets.QToolBar(MainWindow)
self.mainToolBar.setObjectName("mainToolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
self.statusBar = QtWidgets.QStatusBar(MainWindow)
self.statusBar.setObjectName("statusBar")
MainWindow.setStatusBar(self.statusBar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.comboBox.setItemText(0, _translate("MainWindow", "Agnieszka"))
self.comboBox.setItemText(1, _translate("MainWindow", "Monika"))
self.comboBox.setItemText(2, _translate("MainWindow", "Zenek"))
self.label_2.setText(_translate("MainWindow", "zl"))
self.label.setText(_translate("MainWindow", "Kasjer"))
self.pushButton.setText(_translate("MainWindow", "WYŚLIJ"))
And my code:
from PyQt5 import QtWidgets, QtCore, QtGui, QtPrintSupport
from Ui_Baza_Danych import UiBazaDanych
class InputWindow(QtWidgets.QMainWindow, UiBazaDanych):
def __init__(self):
super().__init__()
self.setupUi(self)
self.show()
QtWidgets.QShortcut(QtCore.Qt.Key_PageDown, self, self.pagedown)
def pagedown(self):
self.focusNextPrevChild(True)
# here should be a method to return selected child's name
import sys
from PyQt5.QtWidgets import QApplication
app = QApplication(sys.argv)
show_all = InputWindow()
sys.exit(app.exec_())
If you want to get the widget that has the focus you must use the focusWidget method of QApplication:
def pagedown(self):
self.focusNextPrevChild(True)
widget = QtWidgets.QApplication.focusWidget()
print(widget)

How to display username after authentication from database in PYQT5

I have 2 class files login-form.py and welcome.py
In login-form.py,authentication of user in performed with sqlite3 database.
Code for login-form.py
from PyQt5 import QtCore, QtGui, QtWidgets
from welcome import Ui_MainWindow
import sqlite3
class Ui_Dialog2(object):
def login_check(self):
uname = self.U_name_text.text()
passw = self.pass_text.text()
connection = sqlite3.connect("login.db")
result = connection.execute("SELECT * FROM USERS WHERE USERNAME = ? AND PASSWORD = ?", (uname, passw))
if (len(result.fetchall()) > 0):
print("Login success")
self.welcomewindow = QtWidgets.QMainWindow()
self.ui = Ui_MainWindow()
self.ui.setupUi(self.welcomewindow)
Dialog.hide()
self.welcomewindow.show()
else:
print("invalid login")
def setupUi2(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(301, 386)
Dialog.setStyleSheet("QDialog{\n"
"background-color: rgb(167, 210, 255);\n"
"}\n"
"QPushButton{\n"
"background-color: rgb(255, 255, 255);\n"
"border:none;\n"
"}\n"
"QLabel{\n"
"color:rgb(255, 23, 54);\n"
"font-size:20px;\n"
"}")
self.U_name_Lable = QtWidgets.QLabel(Dialog)
self.U_name_Lable.setGeometry(QtCore.QRect(20, 110, 111, 21))
self.U_name_Lable.setObjectName("U_name_Lable")
self.Pass_Lable = QtWidgets.QLabel(Dialog)
self.Pass_Lable.setGeometry(QtCore.QRect(20, 150, 111, 21))
self.Pass_Lable.setObjectName("Pass_Lable")
self.label = QtWidgets.QLabel(Dialog)
self.label.setGeometry(QtCore.QRect(60, 30, 201, 31))
font = QtGui.QFont()
font.setPointSize(-1)
self.label.setFont(font)
self.label.setStyleSheet("QLabel#label{\n"
"font-size:30px;\n"
"}")
self.label.setObjectName("label")
self.pass_text = QtWidgets.QLineEdit(Dialog)
self.pass_text.setGeometry(QtCore.QRect(140, 150, 131, 20))
self.pass_text.setObjectName("pass_text")
self.login_button = QtWidgets.QPushButton(Dialog)
self.login_button.setGeometry(QtCore.QRect(140, 190, 61, 23))
self.login_button.setObjectName("login_button")
##############button event################
self.login_button.clicked.connect(self.login_check)
##########################################
self.sighup_button = QtWidgets.QPushButton(Dialog)
self.sighup_button.setGeometry(QtCore.QRect(210, 190, 61, 23))
self.sighup_button.setObjectName("sighup_button")
self.U_name_text = QtWidgets.QLineEdit(Dialog)
self.U_name_text.setGeometry(QtCore.QRect(140, 110, 131, 20))
self.U_name_text.setStyleSheet("")
self.U_name_text.setObjectName("U_name_text")
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.U_name_Lable.setText(_translate("Dialog", "USER NAME"))
self.Pass_Lable.setText(_translate("Dialog", "PASSWORD"))
self.label.setText(_translate("Dialog", "LOGIN FORM"))
self.login_button.setText(_translate("Dialog", "Login"))
self.sighup_button.setText(_translate("Dialog", "Sign-up"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog2()
ui.setupUi2(Dialog)
Dialog.show()
sys.exit(app.exec_())
After login i want to display username in QlineEdit in welcome.py file
code for welcome.py
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(220, 90, 151, 61))
font = QtGui.QFont()
font.setFamily("Times New Roman")
font.setPointSize(28)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setObjectName("label")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(20, 300, 551, 61))
self.lineEdit = QtWidgets.QLineEdit(MainWindow)
self.lineEdit.setGeometry(QtCore.QRect(130, 220, 113, 20))
self.lineEdit.setObjectName("lineEdit")
font = QtGui.QFont()
font.setFamily("Times New Roman")
font.setPointSize(28)
font.setBold(True)
font.setWeight(75)
self.label_2.setFont(font)
self.label_2.setObjectName("label_2")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label.setText(_translate("MainWindow", "Welcome"))
self.label_2.setText(_translate("MainWindow", "Good Morning "))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
I am new to python GUI i dont know how to fetch value from one form to another.
The way you are implementing the solution is not scalable, it will give you many headaches. Qt Designer recommends not to modify the classes or the files that it generates since for example you want to change the color of a window, add some widgets, you will have to rewrite all the logic and that is time and money wasted.
The classes generated by Qt Designer are not widgets, but are classes used to fill a widget.
What you should do is create another file that takes care of the logic and use the classes generated by Qt Designer.
In this case, you must eliminate the changes to the .py files generated using Qt Designer.
Recommendation: use appropriate names for the files, do not use -, since these files can be imported by another file and if you do not comply with the rules of python syntax you will have problems. So change the name of login-form.py to login_form.py.
You must create a new file that will call main.py and in it handle the logic, as it is a QDialog the login will use exec_() instead of show(), and verify that it is called to accept() by the result that returns.
import sqlite3
from PyQt5 import QtCore, QtGui, QtWidgets
from login_form import Ui_Dialog2
from welcome import Ui_MainWindow
class LoginDialog(QtWidgets.QDialog, Ui_Dialog2):
def __init__(self, *args, **kwargs):
QtWidgets.QDialog.__init__(self, *args, **kwargs)
self.setupUi(self)
self.login_button.clicked.connect(self.login_check)
def login_check(self):
uname = self.U_name_text.text()
passw = self.pass_text.text()
connection = sqlite3.connect("login.db")
result = connection.execute("SELECT * FROM USERS WHERE USERNAME = ? AND PASSWORD = ?", (uname, passw))
if result.fetchall():
self.accept()
else:
print("invalid login")
class WelcomeWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
QtWidgets.QMainWindow.__init__(self, *args, **kwargs)
self.setupUi(self)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
login = LoginDialog()
w = WelcomeWindow()
if login.exec_() == QtWidgets.QDialog.Accepted:
username = login.U_name_text.text()
w.lineEdit.setText(username)
w.show()
sys.exit(app.exec_())
The complete example can be found in the following link.

PySide: How to have Input Mask and Place Holder Text at the same time

I'm trying to make a lineEdit widget have place holder text (look like 'MM/DD/YYYY') when not in focus and have input masking (looks like ' / / ', or you can put in slashes through other means) when in focus.
Currently the input mask setInputMask('99/99/9999') takes precedence and I can't figure out a way to put a hasFocus (or similiar) signal on a LineEdit widget.
How would you implement both of these functionalities in one widget?
Would it be easier to leave the place holder text as is and create a method that adds in a slash after entering a certain number of characters?
Also, the flicking cursor is really thick when you set a mask. What's up with that and how do you revert it?
Full code:
from PySide import QtCore, QtGui
class Ui_MainWindow(object):
def myChanges(self):
self.lineEdit.installEventFilter(self.lineEdit.setInputMask('99/99/9999'))
self.lineEdit.setPlaceholderText('MM/DD/YYYY')
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(557, 351)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.lineEdit = QtGui.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(100, 130, 113, 20))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtGui.QLineEdit(self.centralwidget)
self.lineEdit_2.setGeometry(QtCore.QRect(320, 130, 113, 20))
self.lineEdit_2.setObjectName("lineEdit_2")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 557, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.myChanges()
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
If you want a custom behavior of a widget you must create a class that inherits from this, in your case of QLineEdit. To get your specific objective you must use the focusInEvent and focusOutEvent methods as described in the following section:
class LineEdit(QtGui.QLineEdit):
def __init__(self, parent=None):
QtGui.QLineEdit.__init__(self, parent=parent)
self.setPlaceholderText('MM/DD/YYYY')
def focusInEvent(self, event):
self.setInputMask('99/99/9999')
def focusOutEvent(self, event):
self.setInputMask('')
And then you should change to:
self.lineEdit = QtGui.QLineEdit(self.centralwidget)
to:
self.lineEdit = LineEdit(self.centralwidget)

Qt and Python Data

I am writing a Python Programm that mainly consists of Data organized in a Python object and I want to write a GUI using PyQt for it.
Since I want to be able to use the Python part without the GUI as well, I don't want Qt code in my Data structure. Qt encourages you to separate the data model from the GUI/View part of the program, so I thought this approach should be fairly common in PyQt. However I don't understand how the Data is to be connected and kept persistent with the GUI.
I think I understand the model/view concept - but it seems to me that the model in Qt terms is a Qt object as well and would need to be kept in sync with my pure python object so I don't see the point of it.
I guess there is still something crucial that I don't understand yet. Can anyone give me a hint?
Update 1:
Following Armatita's comment I give the following minimal example:
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
#Python Data:
class car:
def __init__(self, name, color):
self.name = name
self.color = color
#Window:
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(650, 510, 75, 23))
self.pushButton.setObjectName("pushButton")
self.treeView = QtWidgets.QTreeView(self.centralwidget)
self.treeView.setGeometry(QtCore.QRect(30, 20, 591, 481))
self.treeView.setObjectName("treeView")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(680, 120, 113, 20))
self.lineEdit.setObjectName("lineEdit")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(630, 120, 46, 13))
self.label.setObjectName("label")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Apply"))
self.label.setText(_translate("MainWindow", "Value"))
if __name__ == "__main__":
#create Data
blue_car = car("family_car", "blue")
red_car = car("sports_car", "red")
#open UI
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
#now I would like to show the cars and their properties (name, color) in the treeview...
In this Example I would like to show the cars I created in the tree view Widget and manipulate them with the input field an the apply button.
There are typically two types of interfaces to widgets in Qt. One is the view version, the other is the widget version (which inherits the view). The easiest to use is the widget version, and for what you seem to be trying to do it is what I recommend.
Also, although its possible to software the way you were doing it is generally better to follow the more common conventions. I've adapted your code (including the way you build the MainWindow) to have the small GUI working with a new method (addCar) to add your car class information to the QTreeWidget:
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
#Python Data:
class car:
def __init__(self, name, color):
self.name = name
self.color = color
#Window:
class Ui_MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(Ui_MainWindow, self).__init__()
self.setupUi()
def setupUi(self):
self.setObjectName("MainWindow")
self.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(self)
self.centralwidget.setObjectName("centralwidget")
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(650, 510, 75, 23))
self.pushButton.setObjectName("pushButton")
# self.treeView = QtWidgets.QTreeView(self.centralwidget)
self.treeView = QtWidgets.QTreeWidget(self.centralwidget)
self.treeView.setColumnCount(1)
self.treeView.setGeometry(QtCore.QRect(30, 20, 591, 481))
self.treeView.setObjectName("treeView")
self.lineEdit = QtWidgets.QLineEdit(self.centralwidget)
self.lineEdit.setGeometry(QtCore.QRect(680, 120, 113, 20))
self.lineEdit.setObjectName("lineEdit")
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setGeometry(QtCore.QRect(630, 120, 46, 13))
self.label.setObjectName("label")
self.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(self)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
self.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(self)
self.statusbar.setObjectName("statusbar")
self.setStatusBar(self.statusbar)
self.retranslateUi()
QtCore.QMetaObject.connectSlotsByName(self)
def addCar(self, car, name):
item = QtWidgets.QTreeWidgetItem([name])
child1 = QtWidgets.QTreeWidgetItem(["Type: " + car.name])
child2 = QtWidgets.QTreeWidgetItem(["Type: " + car.color])
item.addChild(child1)
item.addChild(child2)
self.treeView.addTopLevelItem(item)
def retranslateUi(self):
_translate = QtCore.QCoreApplication.translate
self.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "Apply"))
self.label.setText(_translate("MainWindow", "Value"))
if __name__ == "__main__":
#create Data
blue_car = car("family_car", "blue")
red_car = car("sports_car", "red")
#open UI
app = QtWidgets.QApplication(sys.argv)
# MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
# ui.setupUi(MainWindow)
# Add car object
ui.addCar(blue_car, "Blue Car")
ui.addCar(red_car, "Red Car")
ui.show()
sys.exit(app.exec_())
The result is this:
Also I recommend you try checking out an online quick tutorial for pyQt5 (arbitrary example: zetcode) since if you start building software now using the methodology it seems to me you were trying to apply you'll end up re-writing most of it in the future (I think...). I've made the same mistake in the past.

Menubar created by PyQt Designer

i designed in PyQt-Designer a surface and converted it to a .py
No I´m trying to link a function to a menubar-(button). There is something like open, save, close....
I have tried a lot, but unsuccessfully, i hope you can help me to connect a simple function to the open-button in the menu bar.
for example a function that is linked to the menubar
menubar->open->function(open_path):
def open_path():
root= Tk()
Pfad=askdirectory()
root.destroy
Thank you for your help!
Here is the Code:
from PyQt5 import QtCore, QtGui, QtWidgets
import os
from tkinter import *
from tkinter.filedialog import askdirectory
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("Auswertung Brechzahlbestimmung")
MainWindow.resize(1205, 641)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_5 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_5.setObjectName("gridLayout_5")
self.gridLayout_3 = QtWidgets.QGridLayout()
self.gridLayout_3.setObjectName("gridLayout_3")
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.histogram = QtWidgets.QGraphicsView(self.centralwidget)
self.histogram.setMinimumSize(QtCore.QSize(182, 126))
self.histogram.setMaximumSize(QtCore.QSize(16777215, 126))
self.histogram.setObjectName("histogram")
self.verticalLayout_2.addWidget(self.histogram)
self.gridLayout_3.addLayout(self.verticalLayout_2, 2, 2, 1, 1)
self.label = QtWidgets.QLabel(self.centralwidget)
self.label.setObjectName("label")
self.gridLayout_3.addWidget(self.label, 0, 2, 1, 1)
self.horizontalSlider = QtWidgets.QSlider(self.centralwidget)
self.horizontalSlider.setOrientation(QtCore.Qt.Horizontal)
self.horizontalSlider.setObjectName("horizontalSlider")
self.gridLayout_3.addWidget(self.horizontalSlider, 2, 0, 1, 1)
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setObjectName("label_4")
self.gridLayout_3.addWidget(self.label_4, 0, 0, 1, 1)
self.gridLayout_4 = QtWidgets.QGridLayout()
self.gridLayout_4.setObjectName("gridLayout_4")
self.gridLayout_3.addLayout(self.gridLayout_4, 1, 4, 1, 1)
self.seitenansicht = QtWidgets.QGraphicsView(self.centralwidget)
self.seitenansicht.setMinimumSize(QtCore.QSize(537, 407))
self.seitenansicht.setObjectName("seitenansicht")
self.gridLayout_3.addWidget(self.seitenansicht, 1, 2, 1, 1)
self.verticalSlider = QtWidgets.QSlider(self.centralwidget)
self.verticalSlider.setOrientation(QtCore.Qt.Vertical)
self.verticalSlider.setObjectName("verticalSlider")
self.gridLayout_3.addWidget(self.verticalSlider, 1, 1, 1, 1)
self.draufsicht = QtWidgets.QGraphicsView(self.centralwidget)
self.draufsicht.setMinimumSize(QtCore.QSize(537, 407))
self.draufsicht.setObjectName("draufsicht")
self.gridLayout_3.addWidget(self.draufsicht, 1, 0, 1, 1)
self.referenz = QtWidgets.QGraphicsView(self.centralwidget)
self.referenz.setMinimumSize(QtCore.QSize(70, 0))
self.referenz.setMaximumSize(QtCore.QSize(70, 16777215))
self.referenz.setObjectName("referenz")
self.gridLayout_3.addWidget(self.referenz, 1, 3, 1, 1)
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setObjectName("label_2")
self.gridLayout_3.addWidget(self.label_2, 0, 3, 1, 1)
self.gridLayout_5.addLayout(self.gridLayout_3, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
#Here begins the Menubar
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1205, 20))
self.menubar.setObjectName("menubar")
self.menuDatei = QtWidgets.QMenu(self.menubar)
self.menuDatei.setObjectName("menuDatei")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.toolBar = QtWidgets.QToolBar(MainWindow)
self.toolBar.setObjectName("toolBar")
MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.actionOpen = QtWidgets.QAction(MainWindow)
self.actionOpen.setObjectName("actionOpen")
self.actionSave = QtWidgets.QAction(MainWindow)
self.actionSave.setObjectName("actionSave")
self.actionExport_Picture = QtWidgets.QAction(MainWindow)
self.actionExport_Picture.setObjectName("actionExport_Picture")
self.actionExit = QtWidgets.QAction(MainWindow)
self.actionExit.setObjectName("actionExit")
self.menuDatei.addAction(self.actionSave)
self.menuDatei.addAction(self.actionOpen)
self.menuDatei.addSeparator()
self.menuDatei.addAction(self.actionExport_Picture)
self.menuDatei.addSeparator()
self.menuDatei.addAction(self.actionExit)
self.menubar.addAction(self.menuDatei.menuAction())
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "Auswertung Brechzahlbestimmung"))
self.label.setText(_translate("MainWindow", "Schnitt"))
self.label_4.setText(_translate("MainWindow", "Draufsicht"))
self.label_2.setText(_translate("MainWindow", "n"))
self.menuDatei.setTitle(_translate("MainWindow", "Datei"))
self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar"))
self.actionOpen.setText(_translate("MainWindow", "Open"))
self.actionSave.setText(_translate("MainWindow", "Save"))
self.actionExport_Picture.setText(_translate("MainWindow", "Export Picture"))
self.actionExit.setText(_translate("MainWindow", "Exit"))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
First of all I recommend you read the docs, it recommends not to modify the class generated by Qt Designer, but you must create another class that inherited from a widget and use the class provided by Qt Designer as an interface.
On the other hand it is not necessary to use tkinter, Qt provides widgets to obtain directory paths like QFileDialog.
And finally you have to use the triggered signal of self.actionOpen.
Considering the above the solution is:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
# ...
def retranslateUi(self, MainWindow):
# ...
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.actionOpen.triggered.connect(self.open_file)
#QtCore.pyqtSlot()
def open_file(self):
fdirectory = QtWidgets.QFileDialog.getExistingDirectory(self, "Open Directory")
if fdirectory:
print(fdirectory)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

Categories

Resources