(Aug-13-2019, 06:12 PM)Denni Wrote: [ -> ]Okay I have restructured your Designer Code to be pyqt friendly mimicking what you had done as best that I could and added comments to help you perhaps understand better the various pieces and perhaps the why of them. I did not create the Dictionary nor finish the Clear method as I thought perhaps you would like to give it a go now that things are much more nicely laid out and you can hopefully have an easier time of figuring out where to put the items you need to add. But as I state within the code if you have any questions just ask -- but just keep in mind I would much rather teach you to fish than give you one ;)
# First never import more than you need it makes a program bigger
# than necessary and sometimes introduces hidden issues
# Now I rename the os and sys functions as this helps me see exactly
# where they are from and keeps them from stepping on the toes of any
# other functions that might be named similarly
from os import getcwd as osGetcwd
from sys import exit as sysExit
# I break up Widgets into these two categories to help clarify what each of
# the various Objects are used for further I try not to let the line get too
# long as you can see below but again I am only including the things we are
# going to use within the program and nothing more also because all of PyQt5
# functions start with a capital Q I do not bother renaming and do not see a
# need to include their governing module (aka QtCore, QtGui, and QtWidgets)
from PyQt5.QtCore import QRegExp, Qt
from PyQt5.QtGui import QRegExpValidator
# Widget Container Objects
from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QDockWidget
from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QGridLayout, QGroupBox, QLabel
# Widget Action Objects
from PyQt5.QtWidgets import QLineEdit, QPushButton, QAction, QStyleFactory
# This is your Menu and Tool Bar class it does not handle the Tool Bar
# at this time but it could be expanded to do so fairly easily just
# keep in mind everything on a Tool Bar should come from the Menu Bar
class MenuToolBar(QDockWidget):
def __init__(self, parent):
QDockWidget.__init__(self)
self.Parent = parent
self.MainMenu = parent.menuBar()
# This is used to have a handle to the Menu Items
# should you implement a Tool Bar
self.MenuActRef = {'HelloAct':0,
'ResetAct':0}
# ******* Create the World Menu *******
self.WorldMenu = self.MainMenu.addMenu('World')
# ******* Create World Menu Items *******
self.HelloAct = QAction('&Hello', self)
# In case you have or want to include an Icon
# self.HelloAct = QAction(QIcon('Images/hello.ico'), '&Hello', self)
self.HelloAct.setShortcut("Ctrl+H")
self.HelloAct.setStatusTip('Say Hello to the World')
self.HelloAct.triggered.connect(self.SayHello)
self.MenuActRef['HelloAct'] = self.HelloAct
self.ResetAct = QAction('&Reset', self)
# self.ResetAct = QAction(QIcon('Images/reset.ico'), '&Hello', self)
self.ResetAct.setShortcut("Ctrl+H")
self.ResetAct.setStatusTip('Reset the Dialog')
self.ResetAct.triggered.connect(self.ResetWorld)
self.MenuActRef['ResetAct'] = self.ResetAct
self.OkayAct = QAction('&Okay', self)
# self.OkayAct = QAction(QIcon('Images/okay.ico'), '&Okay', self)
self.OkayAct.setShortcut("Ctrl+O")
self.OkayAct.setStatusTip('Okay?')
self.OkayAct.triggered.connect(self.ItsOkay)
self.MenuActRef['OkayAct'] = self.OkayAct
# ******* Setup the World Menu *******
self.WorldMenu.addAction(self.HelloAct)
self.WorldMenu.addSeparator()
self.WorldMenu.addAction(self.ResetAct)
self.WorldMenu.addSeparator()
self.WorldMenu.addAction(self.OkayAct)
self.InitToolBar()
def InitToolBar(self):
# If you create a Tool Bar initialize it here
pass
# These are the Menu/Tool Bar Actions
# Note: The menu is not where things get done its only
# purpose is to set up and render the Menu and Tool Bars
# as such the Actions performed are Call Backs to the
# Main Handler since the Menu ought not know or care
# what its menu selections actually do (if anything)
# This thus makes your Menu/Tool Class autonomous
def SayHello(self):
self.Parent.MenuSubmit()
def ResetWorld(self):
self.Parent.MenuReset()
def ItsOkay(self):
self.Parent.MenuOkay()
class CenterPanel(QWidget):
def __init__(self, parent):
QWidget.__init__(self)
self.Parent = parent
# Note you only need the "self." handle attached to things
# you plan to manipulate in code otherwise you can just
# create them and use them within the Gui without the putting
# the handle on them like I have done with the QBoxes
self.NumRegex = QRegExp("[0-9._]+")
self.Validatr = QRegExpValidator(self.NumRegex)
#-------
self.lblName = QLabel()
self.lblName.setText('Name')
self.lblNamTyp = QLabel()
self.lblNamTyp.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.lblNamTyp.setText('[-]')
self.txtName = QLineEdit()
#-------
self.lblWeight = QLabel()
self.lblWeight.setText('Weight')
self.lblWgtTyp = QLabel()
self.lblWgtTyp.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.lblWgtTyp.setText('[kg]')
self.txtWeight = QLineEdit()
# Redundant and/or conflicting with Validator
# self.txtWeight.setInputMethodHints(Qt.ImhDigitsOnly)
self.txtWeight.setValidator(self.Validatr)
#-------
self.lblYear = QLabel()
self.lblYear.setText('Year')
self.lblYrTyp = QLabel()
self.lblYrTyp.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.lblYrTyp.setText('[-]')
self.txtYear = QLineEdit()
self.txtYear.setInputMethodHints(Qt.ImhDigitsOnly)
#-------
self.lblPlace = QLabel()
self.lblPlace.setText('Place')
self.lblPlcTyp = QLabel()
self.lblPlcTyp.setAlignment(Qt.AlignRight|Qt.AlignTrailing|Qt.AlignVCenter)
self.lblPlcTyp.setText('[-]')
self.txtPlace = QLineEdit()
self.txtPlace.setInputMethodHints(Qt.ImhDigitsOnly)
self.txtPlace.setReadOnly(True)
#-------
grdTest = QGridLayout()
grdTest.addWidget(self.lblName, 0, 0)
grdTest.addWidget(QLabel(' '), 0, 1)
grdTest.addWidget(self.lblNamTyp, 0, 2)
grdTest.addWidget(self.txtName, 0, 3)
grdTest.addWidget(self.lblWeight, 1, 0)
grdTest.addWidget(QLabel(' '), 1, 1)
grdTest.addWidget(self.lblWgtTyp, 1, 2)
grdTest.addWidget(self.txtWeight, 1, 3)
grdTest.addWidget(self.lblYear, 2, 0)
grdTest.addWidget(QLabel(' '), 2, 1)
grdTest.addWidget(self.lblYrTyp, 2, 2)
grdTest.addWidget(self.txtYear, 2, 3)
grdTest.addWidget(self.lblPlace, 3, 0)
grdTest.addWidget(QLabel(' '), 3, 1)
grdTest.addWidget(self.lblPlcTyp, 3, 2)
grdTest.addWidget(self.txtPlace, 3, 3)
#-------
gbxTest = QGroupBox()
gbxTest.setTitle('Test')
gbxTest.setLayout(grdTest)
#-------
self.lblHidden = QLabel('')
self.HideSet = False
self.btnAddNew = QPushButton()
self.btnAddNew.setText('Add New')
self.btnAddNew.clicked.connect(self.ClearValues)
hbxAddNew = QHBoxLayout()
hbxAddNew.addWidget(self.lblHidden)
hbxAddNew.addStretch(2)
hbxAddNew.addWidget(self.btnAddNew)
#-------
vbxAll = QVBoxLayout()
vbxAll.addWidget(gbxTest)
vbxAll.addLayout(hbxAddNew)
#-------
gbxDetails = QGroupBox()
gbxDetails.setTitle('Details')
gbxDetails.setLayout(vbxAll)
#-------
hbxFinal = QHBoxLayout()
hbxFinal.addWidget(gbxDetails)
#-------
self.setLayout(hbxFinal)
def HandleSubmit(self):
if self.HideSet:
self.HideSet = False
self.lblHidden.setText('')
else:
self.HideSet = True
self.lblHidden.setText('Menu Submit')
def ClearValues(self):
# ------ Code that will loop through the QLineEdits ---------
# I am leaving this for you to give a stab at now that
# everything I hope is much easier to understand but
# feel free to ask questions if you need assistance
pass
# Note while denoted as the MainWindow in this situation it is more
# your main handler and as such it is best to restrict it to doing
# just that and let other classes handle the other stuff -- it also
# helps to maintain the overall perspective of what each piece has
# been designed for
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
# MainWindow is made up of 4 areas Menu Bar, Tool Bar, Center Pane, & Status Bar
# It also contains a border region for dockable widget windows
# These are mostly the only things that should appear within your MainWindow
# Yes there might be a few other things but again the purpose of this class is
# to be your Main Coordinator mostly
self.setWindowTitle('Main')
# Note if you are going to be manipulating files with this it should be moved
# to within the module you create to handle that kind of stuff but if you are
# not going to use it then just remove it entirely as it does nothing and can
# always be added later if desired
self.CurntDir = osGetcwd()
# Sometimes its best to place the window where you want but just setting its size
# works as well - I have included both just use the one you prefer
WinLeft = 150; WinTop = 150; WinWidth = 340; WinHight = 220
self.setGeometry(WinLeft, WinTop, WinWidth, WinHight)
# self.resize(WinWidth, WinHight)
self.CenterPane = CenterPanel(self)
self.setCentralWidget(self.CenterPane)
# The Menu and Tool Bar for your MainWindow should be classed as well
self.MenuBar = MenuToolBar(self)
self.SetStatusBar(self)
# Not exactly sure what all this does yet but it does remove
# oddities from the window so I always include it - for now
self.setStyle(QStyleFactory.create('Cleanlooks'))
def SetStatusBar(self, parent):
StatusMsg = ''
parent.StatBar = parent.statusBar()
if len(StatusMsg) < 1:
# This will disappear once you view any menu items
StatusMsg = 'Ready'
parent.StatBar.showMessage(StatusMsg)
def MenuSubmit(self):
# This redirects the Menu Action to the appropriate module
# currently you only have one other module but if you had
# more than one or if this was something that needed to be
# handled here it would be set up differently
self.CenterPane.HandleSubmit()
def MenuReset(self):
# This one actually performs the action
self.StatBar.showMessage('Main Menu Reset Action')
def MenuOkay(self):
# An example of a Menu Call Back that does nothing but again
# the Menu does not know this or even care
pass
if __name__ == "__main__":
# It is best to keep this function to its bare minimum as its
# main purpose is to handle pre-processing stuff
#
# Next you did not appear to be using sys.argv but if you do need
# to use command line arguments I strongly suggest you look into
# argparse its a python library and very helpful for this as such
# also much cleaner than dealing with them via regular means
# otherwise do not include more in your program than you are going
# to actually use -- it creates unnecessary confusion down the road
MainThred = QApplication([])
MainGui = MainWindow()
MainGui.show()
sysExit(MainThred.exec_())
Much appreciated! I will see if I can manage to understand what you did :) but, that is for tomorrow. I will keep you posted.
I am not that experienced, but I tried to understand your structure and I am able to understand it to a certain point.
Hence, I tried (with some help from the internet) to include the clear option by adjusting the code but, it unfortunately does not work.
Most likely because I still miss some important knowledge or taking it a step to far to quickly....
class CenterPanel (QWidget):
def __init__(self, parent):
QWidget.__init__ (self)
self.Parent = parent
# Note you only need the "self." handle attached to things
# you plan to manipulate in code otherwise you can just
# create them and use them within the Gui without the putting
# the handle on them like I have done with the QBoxes
self.NumRegex = QRegExp ("[0-9._]+")
self.Validatr = QRegExpValidator (self.NumRegex)
self.txtNames = {}
# -------
self.lblName = QLabel ()
self.lblName.setText ('Name')
self.lblNamTyp = QLabel ()
self.lblNamTyp.setAlignment (Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)
self.lblNamTyp.setText ('[-]')
self.txtName = QLineEdit ()
# -------
self.lblWeight = QLabel ()
self.lblWeight.setText ('Weight')
self.lblWgtTyp = QLabel ()
self.lblWgtTyp.setAlignment (Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)
self.lblWgtTyp.setText ('[kg]')
self.txtWeight = QLineEdit ()
# Redundant and/or conflicting with Validator
# self.txtWeight.setInputMethodHints(Qt.ImhDigitsOnly)
self.txtWeight.setValidator (self.Validatr)
# -------
self.lblYear = QLabel ()
self.lblYear.setText ('Year')
self.lblYrTyp = QLabel ()
self.lblYrTyp.setAlignment (Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)
self.lblYrTyp.setText ('[-]')
self.txtYear = QLineEdit ()
self.txtYear.setInputMethodHints (Qt.ImhDigitsOnly)
# -------
self.lblPlace = QLabel ()
self.lblPlace.setText ('Place')
self.lblPlcTyp = QLabel ()
self.lblPlcTyp.setAlignment (Qt.AlignRight | Qt.AlignTrailing | Qt.AlignVCenter)
self.lblPlcTyp.setText ('[-]')
self.txtPlace = QLineEdit ()
self.txtPlace.setInputMethodHints (Qt.ImhDigitsOnly)
# -------
grdTest = QGridLayout ()
grdTest.addWidget (self.lblName, 0, 0)
grdTest.addWidget (QLabel (' '), 0, 1)
grdTest.addWidget (self.lblNamTyp, 0, 2)
grdTest.addWidget (self.txtName, 0, 3)
self.txtNames = {'txtName':''}
grdTest.addWidget (self.lblWeight, 1, 0)
grdTest.addWidget (QLabel (' '), 1, 1)
grdTest.addWidget (self.lblWgtTyp, 1, 2)
grdTest.addWidget (self.txtWeight, 1, 3)
grdTest.addWidget (self.lblYear, 2, 0)
grdTest.addWidget (QLabel (' '), 2, 1)
grdTest.addWidget (self.lblYrTyp, 2, 2)
grdTest.addWidget (self.txtYear, 2, 3)
grdTest.addWidget (self.lblPlace, 3, 0)
grdTest.addWidget (QLabel (' '), 3, 1)
grdTest.addWidget (self.lblPlcTyp, 3, 2)
grdTest.addWidget (self.txtPlace, 3, 3)
# -------
gbxTest = QGroupBox ()
gbxTest.setTitle ('Test')
gbxTest.setLayout (grdTest)
# -------
self.lblHidden = QLabel ('')
self.HideSet = False
self.btnAddNew = QPushButton ()
self.btnAddNew.setText ('Add New')
self.btnAddNew.clicked.connect (self.ClearValues)
hbxAddNew = QHBoxLayout ()
hbxAddNew.addWidget (self.lblHidden)
hbxAddNew.addStretch (2)
hbxAddNew.addWidget (self.btnAddNew)
# -------
vbxAll = QVBoxLayout ()
vbxAll.addWidget (gbxTest)
vbxAll.addLayout (hbxAddNew)
# -------
gbxDetails = QGroupBox ()
gbxDetails.setTitle ('Details')
gbxDetails.setLayout (vbxAll)
# -------
hbxFinal = QHBoxLayout ()
hbxFinal.addWidget (gbxDetails)
# -------
self.setLayout (hbxFinal)
def HandleSubmit(self):
if self.HideSet:
self.HideSet = False
self.lblHidden.setText ('')
else:
self.HideSet = True
self.lblHidden.setText ('Menu Submit')
def ClearValues(self):
# ------ Code that will loop through the QLineEdits ---------
# I am leaving this for you to give a stab at now that
# everything I hope is much easier to understand but
# feel free to ask questions if you need assistance
for item in self.txtNames.keys():
getattr(self.Parent, item).setText(self.txtNames[item])
To summarise, I added the following lines: 11,61,121,122
Which results in the following error:
Error:
Traceback (most recent call last):
File "C:/Users/Usr/Desktop/Work Folder PPM/VirtualEnvironment/Scripts/TestDenni.py", line 216, in ClearValues
getattr(self.Parent, item).setText(self.txtNames[item])
AttributeError: 'MainWindow' object has no attribute 'txtName'