Qt QlineEdit pop-up / air message

I am trying to create a generic class in python that will do some error checking for input in qlineEdit (or something else regarding a widget) that will display a balloon telling the user that the entry is invalid. Sort of:

enter image description here

So far I have created this:

enter image description here

My real question is: How do I get the correct qlineEdit widget coordinates to put the balloon in the correct position? The following code should place it in the lower left corner of QlineEdit? It is located below, but not on the left side.


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()

ui file: testErrorMessage.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>493</width>
    <height>348</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QVBoxLayout" name="verticalLayout">
    <item>
     <widget class="QGroupBox" name="groupBox">
      <property name="title">
       <string>groupBox1</string>
      </property>
      <layout class="QGridLayout" name="gridLayout">
       <item row="0" column="0">
        <widget class="QGroupBox" name="groupBox_4">
         <property name="title">
          <string>groupBoxA</string>
         </property>
         <layout class="QHBoxLayout" name="horizontalLayout_2">
          <item>
           <widget class="QLabel" name="label_2">
            <property name="text">
             <string>LineEdit1</string>
            </property>
           </widget>
          </item>
          <item>
           <widget class="QLineEdit" name="lineEdit1"/>
          </item>
         </layout>
        </widget>
       </item>
       <item row="0" column="1">
        <widget class="QGroupBox" name="groupBox_3">
         <property name="title">
          <string>groupBoxB</string>
         </property>
         <layout class="QGridLayout" name="gridLayout_2">
          <item row="0" column="0">
           <widget class="QLabel" name="label">
            <property name="text">
             <string>LineEdit2</string>
            </property>
           </widget>
          </item>
          <item row="0" column="1">
           <widget class="QLineEdit" name="lineEdit2"/>
          </item>
         </layout>
        </widget>
       </item>
      </layout>
     </widget>
    </item>
    <item>
     <widget class="QGroupBox" name="groupBox_2">
      <property name="title">
       <string>groupBox2</string>
      </property>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <widget class="QLabel" name="label_3">
         <property name="text">
          <string>LineEdit3</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="QLineEdit" name="lineEdit3"/>
       </item>
      </layout>
     </widget>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>493</width>
     <height>21</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuFile">
    <property name="title">
     <string>File</string>
    </property>
    <addaction name="actionClose"/>
   </widget>
   <addaction name="menuFile"/>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
  <action name="actionClose">
   <property name="text">
    <string>Close</string>
   </property>
  </action>
 </widget>
 <resources/>
 <connections>
  <connection>
   <sender>actionClose</sender>
   <signal>triggered()</signal>
   <receiver>MainWindow</receiver>
   <slot>close()</slot>
   <hints>
    <hint type="sourcelabel">
     <x>-1</x>
     <y>-1</y>
    </hint>
    <hint type="destinationlabel">
     <x>399</x>
     <y>299</y>
    </hint>
   </hints>
  </connection>
 </connections>
</ui>

Any other ideas on how to make this better?

Thank!

+3
source share
2 answers

QWidget.mapTo -.

, :

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

:

    widget.pos()

, :

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

, pos() ( ), .

:

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

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]))

QLabel !

+1

All Articles