Error Message Pop-Up for Qt QlineEdit

To tackle the issue, there are two solutions. Firstly, in QMainWindow, and secondly, by implementing a normal solution that requires adding new code. However, it should be noted that having too many apps in the trays can be bothersome. Therefore, one must ensure that their app genuinely requires an icon tray. By default, a Qt application shuts down when the final window is closed. Hence, if the box is closed, but the windows remain hidden, the app will shut down.


Question:

My goal is to develop a Python script, specifically
generic class
, which will perform input error checking on a qlineEdit or any other widget. If the input is invalid, a notification balloon will appear, informing the user of the issue.

So far I have manged this:

I am wondering how to obtain the accurate coordinates of the qlineEdit widget to ensure that the balloon appears in the correct location. The code I am using is currently placing the balloon at the bottom, but not precisely on the left-hand side as intended.


Current Code:

import sys
from PyQt4 import QtGui, QtCore, uic
class widgetErrorChecking(QtGui.QLabel):
    def __init__(self, parent, widget, app):
        QtGui.QLabel.__init__(self, parent)
        self.widget = widget
        self.hide()
        effect = QtGui.QGraphicsDropShadowEffect()
        effect.setBlurRadius(10)
        effect.setOffset(2,2)
        self.setGraphicsEffect(effect)
        self.setStyleSheet('''QLabel {
                                 background-color:red;
                                 border: darkRed;
                                 border-radius: 5px;
                                 }
                           ''')
        if isinstance(widget, QtGui.QLineEdit):
            widget.textEdited.connect(self.checkWidgetValue)
        app.focusChanged.connect(self.hide)
    def checkWidgetValue(self, value):
        if not value:
            return
        try:
            value = float(value)
        except ValueError:
            value = 0.0
        if 0.0 >value:
            self.showMessage('Needs to be greater then 0.0')
        elif value>100:
            self.showMessage('Needs to be less then 100.0')
        else:
            self.hide()
    def showMessage(self, message = None):
        '''
        Show the widget.
        '''
        self.setText(message)
        self.adjustSize()
        self.update()
        self.show()
        labelGeo = self.geometry()
        # vvvv whats wrong with this vvvv
        widgetPos = self.widget.mapTo(self.parent(), self.widget.pos())
        widgetGeo = self.widget.geometry()
        newPos = QtCore.QPoint(widgetPos.x(), widgetPos.y()+widgetGeo.height())
        self.move(newPos)
class mainWindow(QtGui.QMainWindow):
    '''
    Main window class handeling all gui interactions
    '''
    def __init__(self, app):
        QtGui.QMainWindow.__init__(self)
        self.app = app
        self.ui =  uic.loadUi('testErrorMessage.ui', self)
        # Add error checking
        errorChecker1 = widgetErrorChecking(self, self.ui.lineEdit1, self.app)
        errorChecker2 = widgetErrorChecking(self, self.ui.lineEdit2, self.app)
        errorChecker3 = widgetErrorChecking(self, self.ui.lineEdit3, self.app)
if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    gui = mainWindow(app)
    gui.show()
    app.exec_()
    app.deleteLater()
    sys.exit()


The file name for the UI is “testErrorMessage.ui.



 MainWindow
 
  
   
    0
    0
    493
    348
   
  
  
   MainWindow
  
  
   
    
     
      
       groupBox1
      
      
       
        
         
          groupBoxA
         
         
          
           
            
             LineEdit1
            
           
          
          
           
          
         
        
       
       
        
         
          groupBoxB
         
         
          
           
            
             LineEdit2
            
           
          
          
           
          
         
        
       
      
     
    
    
     
      
       groupBox2
      
      
       
        
         
          LineEdit3
         
        
       
       
        
       
      
     
    
   
  
  
   
    
     0
     0
     493
     21
    
   
   
    
     File
    
    
   
   
  
  
  
   
    Close
   
  
 
 
 
  
   actionClose
   triggered()
   MainWindow
   close()
   
    
     -1
     -1
    
    
     399
     299
    
   
  
 


Do you have any alternative solutions to improve this?

Thanks!


Solution 1:

The mapTo method of QWidget transfers the location of a point from the caller’s coordinate system to that of a parent widget.

So the result of:

    widget.mapTo(widget.parentWidget(), QPoint(0, 0))

is exactly equivalent to:

    widget.pos()

It is possible to place the label beneath the line-edit by utilizing the following technique:

    self.move(self.widget.mapTo(
        self.parentWidget(), self.widget.rect().bottomLeft()))


Solution 2:


By manually iterating through a widget’s parents and adding up the

pos()

values of all but the last one (which is the window position), the correct coordinates in reference to the window can be obtained.

Replace:

widgetPos = self.widget.mapTo(self.parent(), self.widget.pos())

With:

w = self.widget
x = []
y = []
while w:
    x.append(w.pos().x())
    y.append(w.pos().y())
    w = w.parent()
widgetPos = QtCore.QPoint(sum(x[:-1]), sum(y[:-1]))

I have successfully placed the

QLabel

where it belongs.

Frequently Asked Questions