2014-02-23 29 views
3

我想在python中創建一個通用類,它將對qlineEdit(或其他控件)中的輸入進行一些錯誤檢查,這將彈出一個氣球,告訴用戶條目無效。喜歡的東西:Qt QlineEdit錯誤彈出框/氣球消息

enter image description here

到目前爲止,我已經manged這樣的:

enter image description here

我真正的問題是:我如何獲得QLineEdit的小部件的正確座標放置氣球在正確的位置?下面的代碼應該放在QlineEdit的左下角?它位於底部,而不是左側。


目前代碼:

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文件: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> 

如何做得更好任何其他的想法?

謝謝!

+0

沒有足夠的代碼來重現問題。此代碼似乎有時工作不正確取決於佈局。你可以發佈你用來創建表單的代碼(和UI文件,如果有的話),並添加'widgetErrorChecking'它? –

+0

@PavelStrakhov我會盡力重現它。目前的UI文件和代碼是巨大的...我試圖讓這個對話框在佈局/小部件結構中非常深入。窗口布局是一個'QVerticalLayout',然後是一個帶有'QGridLayout'的'QTabWidget',然後是一個'QFrame'與另一個'QGridLayout'以及'QGridLayout'中的'QLineEdit'。 – Onlyjus

回答

3

QWidget.mapTo方法映射呼叫者到一個祖先插件的座標系的座標系內的點

這樣的結果:

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

完全等同於:

widget.pos() 

這意味着您可以在在線編輯與底部位置標籤:

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

所以,如果你手動迭代所有部件的父母,並總結pos()除了最後一個(窗口位置)我得到正確的座標參考窗口。

替換:

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

有了:

​​

現在我可以在正確的地方QLabel