Отображение QToolTip у элементов QScrollArea
Нужно сделать так, чтобы QToolTip показывался рядом с пустым полем QLineEdit.
Интерфейс:
from PySide6.QtCore import (QCoreApplication, QDate, QDateTime, QLocale,
QMetaObject, QObject, QPoint, QRect,
QSize, QTime, QUrl, Qt)
from PySide6.QtGui import (QBrush, QColor, QConicalGradient, QCursor,
QFont, QFontDatabase, QGradient, QIcon,
QImage, QKeySequence, QLinearGradient, QPainter,
QPalette, QPixmap, QRadialGradient, QTransform)
from PySide6.QtWidgets import (QApplication, QGridLayout, QHBoxLayout, QLabel,
QLineEdit, QMainWindow, QPushButton, QScrollArea,
QSizePolicy, QWidget)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(554, 363)
MainWindow.setStyleSheet(u"QWidget {\n"
" background-color: white;\n"
" color: black;\n"
" font: 14pt \"Times New Roman\";\n"
" font-weight: 400;\n"
"}\n")
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.centralwidget.setStyleSheet(u"")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.label = QLabel(self.centralwidget)
self.label.setObjectName(u"label")
self.horizontalLayout.addWidget(self.label)
self.age = QLineEdit(self.centralwidget)
self.age.setObjectName(u"age")
self.horizontalLayout.addWidget(self.age)
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
self.scrollArea = QScrollArea(self.centralwidget)
self.scrollArea.setObjectName(u"scrollArea")
self.scrollArea.setMidLineWidth(0)
self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QWidget()
self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents")
self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 522, 261))
self.scrollAreaWidgetContents.setContextMenuPolicy(Qt.NoContextMenu)
self.scrollAreaWidgetContents.setStyleSheet(u"")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.gridLayout.addWidget(self.scrollArea, 1, 0, 1, 1)
self.pushButton = QPushButton(self.centralwidget)
self.pushButton.setFocusPolicy(Qt.FocusPolicy.NoFocus)
self.pushButton.setObjectName(u"pushButton")
self.resul = QLabel(self.centralwidget)
self.resul.setObjectName(u"result")
self.resul.setStyleSheet("border: 1.5px solid black;")
self.resul.setWordWrap(True)
self.gridLayout.addWidget(self.pushButton, 2, 0, 1, 1)
self.gridLayout.addWidget(self.resul)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
self.label.setText(QCoreApplication.translate("MainWindow", u"\u0412\u043e\u0437\u0440\u0430\u0441\u0442", None))
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
# retranslateUi
Исполняемый файл:
import sys
from int import *
class Label(QLabel):
clicked = Signal()
def __init__(self):
super().__init__()
def mouseReleaseEvent(self, event):
self.clicked.emit()
class MyWidget(QWidget):
def __init__(self, res, num):
super().__init__()
self.flag = True
self.label = Label()
self.label.setText(f'{res}')
self.label.setWordWrap(True)
self.label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.label.setStyleSheet(self.stl('none', '10px'))
self.label.setMinimumSize(QSize(0,27))
self.label.setObjectName(f'workout_{num}')
self.label.clicked.connect(self.onClicked)
self.label.setCursor(QCursor(Qt.PointingHandCursor))
self.lineEdit = QLineEdit()
self.lineEdit.setEnabled(False)
self.lineEdit.setAlignment(Qt.AlignCenter)
self.lineEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.lineEdit.setStyleSheet("QLineEdit {border: 1.5px solid black;"
"border-top-right-radius: 10px;"
"border-bottom-right-radius: 10px;"
"border-left-style:none;}"
)
self.lineEdit.setObjectName(f'res_{num}')
self.lineEdit.hide()
layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setStretch(1, 0)
layout.setSpacing(0)
layout.addWidget(self.label, 1)
layout.addWidget(self.lineEdit, 0, alignment=Qt.AlignRight)
def onClicked(self):
if self.flag:
self.label.setStyleSheet(self.stl('#7db1b3', '0'))
self.lineEdit.setEnabled(True)
self.lineEdit.show()
self.lineEdit.setFocus()
else:
self.label.setStyleSheet(self.stl('none', '10px'))
self.lineEdit.hide()
self.lineEdit.setEnabled(False)
self.flag = not self.flag
def stl(self, b, s):
return "QLabel {" + f"background-color: {b};" \
"border: 1.5px solid black;" \
"border-top-left-radius: 10px;" \
f"border-top-right-radius: {s};" \
"border-bottom-left-radius: 10px;" \
f"border-bottom-right-radius: {s};" \
"font: 14pt 'Times New Roman'};" \
"QLabel:hover {border-color: #534F4C;}"
class Test(QMainWindow, Ui_MainWindow):
def __init__(self):
super(Test, self).__init__()
self.setupUi(self)
self.printed()
self.pushButton.clicked.connect(self.cheack2)
def printed(self):
layout = QVBoxLayout()
widget = QWidget()
for i in range(10):
layout.addWidget(MyWidget(i, i))
widget.setLayout(layout)
self.scrollArea.setWidget(widget)
def cheack2(self):
for l in self.scrollArea.findChildren(QLineEdit):
if l.text() == '' and l.isVisible():
self.scrollArea.ensureWidgetVisible(l)
l.setFocus()
self.showToolTip(self.scrollArea, l , 'Пустое поле')
break
@staticmethod
def showToolTip(group, obj: QLineEdit, text: str) -> None:
QToolTip.showText(QWidget.mapToGlobal(group, obj.pos()), text, obj, QRect(), 2000)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Test()
window.show()
sys.exit(app.exec())
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Попробуйте так:
import sys
# установите свои импорты для PySide6 # !!! + QtTest
from PyQt5 import QtCore, QtGui, QtWidgets, QtTest # +++ QtTest
from PyQt5.Qt import *
# --> vvvvvvvvvvvvv <----> vvvvvvvvvvvvv <----------------------------------
#from mainWindow_ui import Ui_MainWindow
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(554, 363)
MainWindow.setStyleSheet(u"QWidget {\n"
" background-color: white;\n"
" color: black;\n"
" font: 14pt \"Times New Roman\";\n"
" font-weight: 400;\n"
"}\n")
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.centralwidget.setStyleSheet(u"")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
self.horizontalLayout = QHBoxLayout()
self.horizontalLayout.setObjectName(u"horizontalLayout")
self.label = QLabel(self.centralwidget)
self.label.setObjectName(u"label")
self.horizontalLayout.addWidget(self.label)
self.age = QLineEdit(self.centralwidget)
self.age.setObjectName(u"age")
self.horizontalLayout.addWidget(self.age)
self.gridLayout.addLayout(self.horizontalLayout, 0, 0, 1, 1)
self.scrollArea = QScrollArea(self.centralwidget)
self.scrollArea.setObjectName(u"scrollArea")
self.scrollArea.setMidLineWidth(0)
self.scrollArea.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.scrollArea.setWidgetResizable(True)
self.scrollAreaWidgetContents = QWidget()
self.scrollAreaWidgetContents.setObjectName(u"scrollAreaWidgetContents")
self.scrollAreaWidgetContents.setGeometry(QRect(0, 0, 522, 261))
self.scrollAreaWidgetContents.setContextMenuPolicy(Qt.NoContextMenu)
self.scrollAreaWidgetContents.setStyleSheet(u"")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
self.gridLayout.addWidget(self.scrollArea, 1, 0, 1, 1)
self.pushButton = QPushButton(self.centralwidget)
self.pushButton.setFocusPolicy(Qt.FocusPolicy.NoFocus)
self.pushButton.setObjectName(u"pushButton")
self.resul = QLabel(self.centralwidget)
self.resul.setObjectName(u"result")
self.resul.setStyleSheet("border: 1.5px solid black;")
self.resul.setWordWrap(True)
self.gridLayout.addWidget(self.pushButton, 2, 0, 1, 1)
self.gridLayout.addWidget(self.resul)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
self.label.setText(QCoreApplication.translate("MainWindow", u"\u0412\u043e\u0437\u0440\u0430\u0441\u0442", None))
self.pushButton.setText(QCoreApplication.translate("MainWindow", u"PushButton", None))
class Label(QLabel):
# clicked = Signal() # PySide6
clicked = pyqtSignal() # PyQt5
def __init__(self):
super().__init__()
def mouseReleaseEvent(self, event):
self.clicked.emit()
class MyWidget(QWidget):
def __init__(self, res, num):
super().__init__()
self.flag = True
self.label = Label()
self.label.setText(f'{res}')
self.label.setWordWrap(True)
self.label.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.label.setStyleSheet(self.stl('none', '10px'))
self.label.setMinimumSize(QSize(0,27))
self.label.setObjectName(f'workout_{num}')
self.label.clicked.connect(self.onClicked)
self.label.setCursor(QCursor(Qt.PointingHandCursor))
self.lineEdit = QLineEdit()
self.lineEdit.setEnabled(False)
self.lineEdit.setAlignment(Qt.AlignCenter)
self.lineEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
self.lineEdit.setStyleSheet("QLineEdit {border: 1.5px solid black;"
"border-top-right-radius: 10px;"
"border-bottom-right-radius: 10px;"
"border-left-style:none;}"
)
self.lineEdit.setObjectName(f'res_{num}')
self.lineEdit.hide()
layout = QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setStretch(1, 0)
layout.setSpacing(0)
layout.addWidget(self.label, 1)
layout.addWidget(self.lineEdit, 0, alignment=Qt.AlignRight)
def onClicked(self):
if self.flag:
self.label.setStyleSheet(self.stl('#7db1b3', '0'))
self.lineEdit.setEnabled(True)
self.lineEdit.show()
self.lineEdit.setFocus()
else:
self.label.setStyleSheet(self.stl('none', '10px'))
self.lineEdit.hide()
self.lineEdit.setEnabled(False)
self.flag = not self.flag
def stl(self, b, s):
return "QLabel {" + f"background-color: {b};" \
"border: 1.5px solid black;" \
"border-top-left-radius: 10px;" \
f"border-top-right-radius: {s};" \
"border-bottom-left-radius: 10px;" \
f"border-bottom-right-radius: {s};" \
"font: 14pt 'Times New Roman'};" \
"QLabel:hover {border-color: #534F4C;}"
class Test(QMainWindow, Ui_MainWindow):
def __init__(self):
super(Test, self).__init__()
self.setupUi(self)
self.printed()
self.pushButton.clicked.connect(self.cheack2)
def printed(self):
layout = QVBoxLayout()
widget = QWidget()
for i in range(10):
layout.addWidget(MyWidget(i, i))
widget.setLayout(layout)
self.scrollArea.setWidget(widget)
def cheack2(self):
lineEdits = self.scrollArea.findChildren(QLineEdit)
for le in lineEdits:
if le.text() == '' and le.isVisible():
self.scrollArea.ensureWidgetVisible(le)
le.setFocus()
self.showToolTip(
self.scrollArea, le , '<h2 style="color: red;">Пустое поле</h2>')
# ??? break
@staticmethod
def showToolTip(group, obj: QLineEdit, text: str) -> None:
QToolTip.showText(
# ----------------------------> vvvvvvvvvvvv <----------------------------------
QWidget.mapToGlobal(obj.parent(), obj.pos()), # !!!
text, obj, QRect(), 2000
)
QtTest.QTest.qWait(2000) # !!! +++
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Test()
window.show()
sys.exit(app.exec())

