PyQt5 无法获取功能和 类 正确

PyQt5 cannot get function and classes right

您好,需要帮助了解为什么不起作用认为是概念性的,但我无法理解。

我有一些文件:

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>

我从网上复制了这个例子: 先开window, 按钮C, 打开新 window, 只能插入整数(QIntValidator), 尝试插入输入 QLineEdit 背景时更改颜色。

问题是我无法在外部文件上获取 check_state() 函数。 为了让它工作,我需要将它放在 main.py 文件中(将 # 添加到 from checkstate import check_state 并从 main.py 上的 def check_state 中删除 ####) 为什么我无法从外部文件中获取函数??

另一方面,为什么 QIntValidator 会阻止我的退格(backcancel)键盘键工作?

您有 2 个错误:

  • sender() 方法属于 QObject,显然 "check_state" 不属于任何 class,更不用说 QObject 了。

  • "self.check_state" 表示 class 有 check_state 这显然不是真的。

因此您将不得不不使用 sender() 而是通过 lambda 函数传递对象来实现逻辑(有关详细信息,请参阅 ):

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]
    # ...