我正在尝试在python中创建一个泛型类,它将对qlineEdit(或其他小部件)中的输入进行一些错误检查,这将弹出一个气球告诉用户该条目无效。类似的东西:
到目前为止,我已经对此进行了管理:
我真正的问题是: 如何获取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 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>
关于如何做得更好的任何其他想法?
谢谢!
答案 0 :(得分:3)
QWidget.mapTo方法将调用者的坐标系内的点映射到祖先小部件的坐标系。
结果:
widget.mapTo(widget.parentWidget(), QPoint(0, 0))
完全等同于:
widget.pos()
这意味着您可以使用以下符号将标签放置在行编辑的底部:
self.move(self.widget.mapTo(
self.parentWidget(), self.widget.rect().bottomLeft()))
答案 1 :(得分:1)
因此,如果您手动遍历所有窗口小部件的父窗口,并总结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
放在正确的位置!