python-3.xclasspyqt5designerqvalidator

PyQt5 cannot get function and classes right


Hi need help about why is not working think is conceptual but I cannot grasp it.

I have some files:

main.py :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr  8 14:25:12 2020

@author: Pietro
"""

import sys
from PyQt5 import QtWidgets, uic, QtCore, QtGui
from PyQt5.QtCore import QTimer, Qt
from inputgui import Inputgui

from checkstate import check_state

class Menu(QtWidgets.QMainWindow):

    def __init__(self): 
        super(Menu, self).__init__()
        uic.loadUi('main2.ui', self)
        self.setFixedSize(544,686)
        self.show()         
        self.ButtonC.clicked.connect(self.inputs)  

    def inputs(self):
        self.hide()                                                                  
        self.inputguiwin=Inputgui()   
        self.inputguiwin.show()
        self.validator = QtGui.QIntValidator()
        self.inputguiwin.annualsalaryinput.setValidator(self.validator) 
        self.inputguiwin.annualsalaryinput.textChanged.connect(self.check_state)
        self.inputguiwin.annualsalaryinput.textChanged.emit(self.inputguiwin.annualsalaryinput.text())
        self.inputguiwin.pushButtonOK.clicked.connect(self.qpushButtonOKpressed)
        self.inputguiwin.pushButtonCANCEL.clicked.connect(self.pushButtonCANCELpressed)

#    def check_state(self):        
#        sender = self.sender()
#        validator = sender.validator()      
#        state = validator.validate(sender.text(), 0)[0]
#        if state == QtGui.QIntValidator.Acceptable:            
#            color = 'green'       
#        elif state == QtGui.QIntValidator.Intermediate:           
#            color = 'yellow'        
#        else:            
#            color = 'red'            
#        sender.setStyleSheet('QLineEdit { background-color: %s }' % color)        

if __name__ == '__main__':             
    app = QtWidgets.QApplication(sys.argv)
    window=Menu()
    sys.exit(app.exec_())

inputgui.py :

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Tue Apr 14 10:40:44 2020

@author: bob
"""

import sys
from PyQt5 import QtWidgets, uic, QtCore
import resource



class Inputgui(QtWidgets.QMainWindow):


    def __init__(self):
        super(Inputgui, self).__init__()
        uic.loadUi('inputgui2.ui', self)
        self.setFixedSize(904,661)
        print('inside inputgui ' *5)       


if __name__ == '__main__': 
    app = QtWidgets.QApplication(sys.argv)
    pollo=Inputgui()
    sys.exit(app.exec_())

checkstate.py :

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
"""
Created on Sun Apr 19 20:28:32 2020

@author: bob
"""

import sys
from PyQt5 import QtWidgets, uic, QtCore, QtGui
from PyQt5.QtCore import QTimer, Qt


def check_state(self):        
    sender = self.sender()
    validator = sender.validator()      
    state = validator.validate(sender.text(), 0)[0]
    if state == QtGui.QIntValidator.Acceptable:            
        color = 'green'       
    elif state == QtGui.QIntValidator.Intermediate:           
        color = 'yellow'        
    else:            
        color = 'red'            
    sender.setStyleSheet('QLineEdit { background-color: %s }' % color) 

main2.ui :

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="windowModality">
   <enum>Qt::WindowModal</enum>
  </property>
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>487</width>
    <height>415</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <property name="windowIcon">
   <iconset>
    <normaloff>:/main/python.png</normaloff>
    <normalon>:/main/python.png</normalon>
    <disabledoff>:/main/python.png</disabledoff>
    <disabledon>:/main/python.png</disabledon>
    <activeoff>:/main/python.png</activeoff>
    <activeon>:/main/python.png</activeon>
    <selectedoff>:/main/python.png</selectedoff>
    <selectedon>:/main/python.png</selectedon>:/main/python.png</iconset>
  </property>
  <property name="styleSheet">
   <string notr="true"/>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QPushButton" name="ButtonC">
    <property name="geometry">
     <rect>
      <x>150</x>
      <y>110</y>
      <width>151</width>
      <height>81</height>
     </rect>
    </property>
    <property name="font">
     <font>
      <pointsize>20</pointsize>
      <weight>75</weight>
      <bold>true</bold>
     </font>
    </property>
    <property name="text">
     <string>C</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>487</width>
     <height>29</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

inputgui2.ui :

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="windowModality">
   <enum>Qt::WindowModal</enum>
  </property>
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>422</width>
    <height>276</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <property name="layoutDirection">
   <enum>Qt::LeftToRight</enum>
  </property>
  <property name="autoFillBackground">
   <bool>true</bool>
  </property>
  <property name="styleSheet">
   <string notr="true">QPushButton#pushButtonOK{
    background-color: #9de650;
}


QPushButton:hover#pushButtonOK{
    background-color: green;
}


QPushButton#pushButtonCANCEL{
    background-color: orange;
}


QPushButton:hover#pushButtonCANCEL{
    background-color: red;
}
</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLineEdit" name="annualsalaryinput">
    <property name="geometry">
     <rect>
      <x>80</x>
      <y>80</y>
      <width>131</width>
      <height>51</height>
     </rect>
    </property>
    <property name="contextMenuPolicy">
     <enum>Qt::DefaultContextMenu</enum>
    </property>
    <property name="layoutDirection">
     <enum>Qt::RightToLeft</enum>
    </property>
    <property name="text">
     <string>   Annual Salary</string>
    </property>
    <property name="alignment">
     <set>Qt::AlignCenter</set>
    </property>
    <property name="clearButtonEnabled">
     <bool>true</bool>
    </property>
   </widget>
   <widget class="QLabel" name="annualsalarylabel">
    <property name="geometry">
     <rect>
      <x>230</x>
      <y>90</y>
      <width>151</width>
      <height>41</height>
     </rect>
    </property>
    <property name="text">
     <string> Annual Salary</string>
    </property>
   </widget>
   <widget class="QLabel" name="titlelabel">
    <property name="geometry">
     <rect>
      <x>210</x>
      <y>0</y>
      <width>471</width>
      <height>71</height>
     </rect>
    </property>
    <property name="font">
     <font>
      <pointsize>16</pointsize>
      <weight>75</weight>
      <bold>true</bold>
      <underline>true</underline>
     </font>
    </property>
    <property name="styleSheet">
     <string notr="true"/>
    </property>
    <property name="text">
     <string/>
    </property>
    <property name="alignment">
     <set>Qt::AlignCenter</set>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>422</width>
     <height>29</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

I copied this example from the web: open first window, push button C, open new window, can only insert integer (QIntValidator), when trying to inset input QLineEdit background change color.

Problem is I cannot get the check_state() function on an external file. To have it work I need to have it on main.py file (add # to from checkstate import check_state and remove #### from def check_state on main.py) Why I cannot get the function from external file ??

On another side why QIntValidator prevents my backspace (backcancel) keyboard key to work??


Solution

  • You have 2 errors:

    So you will have to implement the logic not using sender() but passing the object through a lambda function(see this for more information):

    self.inputguiwin.annualsalaryinput.textChanged.connect(lambda text, sender=self.inputguiwin.annualsalaryinput: self.check_state(sender))
    
    def check_state(sender):        
        validator = sender.validator()      
        state = validator.validate(sender.text(), 0)[0]
        # ...