0

The first sample program works fine. The program opens a NumPad when user clicks one of the arrayed QLineEdit cells and when user, using mouse picks number and presses "Enter" the number is placed in the selected QLineEdit cell and NumPad is closed. However, when a calling screen is added in the second program to open screen "ss" the "ss.lVal[(..." and "ss.numpad.close()" lines stop working.

Working Sample Code:

#!/usr/bin/env python

import sys
from pprint import pprint
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import pyqtSignal
from PyQt5 import QtCore, QtGui, QtWidgets

# Global variables
# Data Select - 3=3 Data Rows,4=4 Data Rows,5=5 DataRows
gvDataSel = 3
gvPickX = 0
gvPickY = 0

class extQLineEdit(QLineEdit):
    clicked=pyqtSignal()
    def __init__(self,parent):
        QLineEdit.__init__(self,parent)
    def mousePressEvent(self,QMouseEvent):
        self.clicked.emit()


class wdScoreSheet(QWidget):
    def __init__(self):
        super(wdScoreSheet, self).__init__()

        global gvDataSel

        self.resize(400, 300)

        self.numpad = NumPad(self)

        # Value array
        self.lVal = {}
        for i in range(gvDataSel):
            for j in range(2):
                k = 0
                self.lVal[i,j] = extQLineEdit(self)
                self.lVal[i,j].setGeometry(QtCore.QRect(((j*140)+10),((i*34)+50), 50, 28))
                self.lVal[i,j].clicked.connect(lambda i=i, j=j: self.show_NumPad(i,j))


    def show_NumPad(self, parm1, parm2):
        global gvPickX
        global gvPickY
        gvPickX = parm1
        gvPickY = parm2
        self.numpad.show()

    def close(self):
        self.numpad.close()
        super(wdScoreSheet, self).close()


class NumPad(QWidget):
    def __init__(self, parm1):
        super(NumPad, self).__init__()

        grid_layout = QGridLayout()
        self.setLayout(grid_layout)
        values = [
            '1', '2', '3',
            '4', '5', '6',
            '7', '8', '9',
            '-', '0', 'Enter'
        ]
        positions = [(i, j) for i in range(1,5) for j in range(3)]
        # position is an array of tuples
        for position, value in zip(positions, values):
            if value == '':
                continue
            button = QPushButton(value)
            grid_layout.addWidget(button, *position)
            button.clicked.connect(self.btnclick)

        self.setWindowTitle('Num Pad')

        verticalLayout = QVBoxLayout()
        self.lineEdit = QLineEdit()
        verticalLayout.addWidget(self.lineEdit)
        grid_layout.addLayout(verticalLayout, 0, 0, 1, 3)



    def btnclick(self):
        sender = self.sender()
        #pprint("You Pressed: " + sender.text())
        if sender.text() in ['0','1','2','3','4','5','6','7','8','9']:
            self.lineEdit.setText(self.lineEdit.text() + sender.text())

        if sender.text() in ['-']:
            if self.lineEdit.text()[:1] in ['-']:
                self.lineEdit.setText(self.lineEdit.text()[-(len(self.lineEdit.text())-1):])
            else:
                self.lineEdit.setText(sender.text() + self.lineEdit.text())

        if sender.text() in ["Enter"]:
            if self.lineEdit.text() not in [""]:
                ss.lVal[(gvPickX, gvPickY)].setText(self.lineEdit.text())
            self.lineEdit.clear()
            ss.numpad.close()



if __name__ == "__main__":
    app = QApplication(sys.argv)
    ss = wdScoreSheet()
    ss.show()
    sys.exit(app.exec_())

Same Code with MainWindow added that does not work:

#!/usr/bin/env python

import sys
from pprint import pprint
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QApplication
from PyQt5.QtWidgets import QLineEdit
from PyQt5.QtWidgets import QPushButton
from PyQt5.QtWidgets import QVBoxLayout
from PyQt5.QtWidgets import QMainWindow
from PyQt5.QtWidgets import QWidget
from PyQt5.QtWidgets import QGridLayout
from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import pyqtSignal
from PyQt5 import QtCore, QtGui, QtWidgets

# Global variables
# Data Select - 3=3 Data Rows,4=4 Data Rows,5=5 DataRows
gvDataSel = 3
gvPickX = 0
gvPickY = 0

class extQLineEdit(QLineEdit):
    clicked=pyqtSignal()
    def __init__(self,parent):
        QLineEdit.__init__(self,parent)
    def mousePressEvent(self,QMouseEvent):
        self.clicked.emit()


class wdScoreSheet(QWidget):
    def __init__(self):
        super(wdScoreSheet, self).__init__()

        global gvDataSel

        self.resize(400, 300)

        self.numpad = NumPad(self)

        # Value array
        self.lVal = {}
        for i in range(gvDataSel):
            for j in range(2):
                k = 0
                self.lVal[i,j] = extQLineEdit(self)
                self.lVal[i,j].setGeometry(QtCore.QRect(((j*140)+10),((i*34)+50), 50, 28))
                self.lVal[i,j].clicked.connect(lambda i=i, j=j: self.show_NumPad(i,j))


    def show_NumPad(self, parm1, parm2):
        global gvPickX
        global gvPickY
        gvPickX = parm1
        gvPickY = parm2
        self.numpad.show()

    def close(self):
        self.numpad.close()
        super(wdScoreSheet, self).close()


class NumPad(QWidget):
    def __init__(self, parm1):
        super(NumPad, self).__init__()

        grid_layout = QGridLayout()
        self.setLayout(grid_layout)
        values = [
            '1', '2', '3',
            '4', '5', '6',
            '7', '8', '9',
            '-', '0', 'Enter'
        ]
        positions = [(i, j) for i in range(1,5) for j in range(3)]
        # position is an array of tuples
        for position, value in zip(positions, values):
            if value == '':
                continue
            button = QPushButton(value)
            grid_layout.addWidget(button, *position)
            button.clicked.connect(self.btnclick)

        self.setWindowTitle('Num Pad')

        verticalLayout = QVBoxLayout()
        self.lineEdit = QLineEdit()
        verticalLayout.addWidget(self.lineEdit)
        grid_layout.addLayout(verticalLayout, 0, 0, 1, 3)



    def btnclick(self):
        sender = self.sender()
        #pprint("You Pressed: " + sender.text())
        if sender.text() in ['0','1','2','3','4','5','6','7','8','9']:
            self.lineEdit.setText(self.lineEdit.text() + sender.text())

        if sender.text() in ['-']:
            if self.lineEdit.text()[:1] in ['-']:
                self.lineEdit.setText(self.lineEdit.text()[-(len(self.lineEdit.text())-1):])
            else:
                self.lineEdit.setText(sender.text() + self.lineEdit.text())

        if sender.text() in ["Enter"]:
            if self.lineEdit.text() not in [""]:
                ss.lVal[(gvPickX, gvPickY)].setText(self.lineEdit.text())
            self.lineEdit.clear()
            ss.numpad.close()

class wdMainWindow(QMainWindow):
    def __init__(self):
        super(wdMainWindow, self).__init__()
        self.resize(400, 300)

        self.pbSHR = QPushButton(self)
        self.pbSHR.setText("Open Data Screen")
        self.pbSHR.setGeometry(QtCore.QRect(20, 20, 200, 30))
        self.pbSHR.clicked.connect(self.pbSHR_clicked)

    def pbSHR_clicked(self):
        global gvDataSel
        gvDataSel = 4
        ss = wdScoreSheet()
        ss.show()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    mw = wdMainWindow()
    mw.show()
    sys.exit(app.exec_())

Adding MainWindow to call ss (open instance of wdScoreSheet) makes "ss.lVal[(..." and "ss.numpad.close()" now fail, why? What needs to be changed to make NumPad work like the first program? Thank you in advance for your help.

Michael H
  • 1
  • 1
  • I see your response that this issue has been answered, and I have reviewed those answers, both the scope answer and the use of global variables. I'll cover the global problem later below but, I feel my issue is a scope problem. Closing the NumPad works, I think, in the first code because it's instance is in the scope of "ss" and that child can be closed, why is not still in the scope of "ss" when it is launched by "mw". This is my main question i am trying to solve. As for the global variables, it was not my desired method, but pass the parameters did not work when I tried. – Michael H Dec 20 '18 at 17:08
  • If you have read the answers correctly you will have understood that a variable must exist as long as it is necessary, for example if you want a variable to be accessed within a class then make it a member of the class, if you only want it to be necessary within a function then it should only be a local variable. If you want to access a variable that is defined in another class, access through the object of that class. On the other hand, if you do not take it as a reference, you will always have problems and the debugging will be complicated and confusing. – eyllanesc Dec 20 '18 at 21:02

0 Answers0