Форум сайта python.su
Хочу обрабатывать приобретение/потерю фокуса своего виджета. Для QLineEdit способ работает, а вот для самодельного QSelectPath нет, почему так происходит, ну или как выйти из этой ситуации?
import sys from PyQt4 import QtGui, QtCore class Example(QtGui.QWidget): def __init__(self): super(Example, self).__init__() self.initUI() self.inFocus = ('', '') # Элемент (и его данные), который последним был в фокусе def initUI(self): self.setGeometry(300, 300, 280, 170) self.setWindowTitle('Hello!') self.a = QtGui.QLineEdit(self) self.a.installEventFilter(self) self.a.move(60, 50) self.a.setFocus() self.b = QSelectPath(self) self.b.installEventFilter(self) self.b.move(60, 100) def eventFilter(self, obj, event): if obj == self.inFocus[0]: if event.type() == QtCore.QEvent.FocusOut: print('Фокус потерян') else: if event.type() == QtCore.QEvent.FocusIn: self.inFocus = (obj, obj.text()) print('В фокусе') return False class QSelectPath(QtGui.QWidget): """ Виджет для выбора пути к папке """ def __init__(self, parent=None): super(QSelectPath, self).__init__(parent) self.buildWidget() def buildWidget(self): mainLayout = QtGui.QHBoxLayout() mainLayout.setContentsMargins(0, 0, 0, 0) # Убираем внешние отступы у компановщика self.path = QtGui.QLineEdit(self) self.path.setReadOnly(True) overview = QtGui.QPushButton('Обзор', self) self.connect(overview, QtCore.SIGNAL('clicked()'), self.chooseFile) mainLayout.addWidget(self.path) mainLayout.addWidget(overview) self.setLayout(mainLayout) def chooseFile(self): """ Открывает диалоговое окно выбора папки """ path = QtGui.QFileDialog.getExistingDirectory(self, 'Выберите папку') if path: self.path.setText(path) def text(self): return self.path.text() def setText(self, string): self.path.setText(string) if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = Example() window.show() sys.exit(app.exec_())
Офлайн
self.b.setFocusPolicy(QtCore.Qt.StrongFocus)
Офлайн
Rodegast
Добавил это к своему коду и ничего не изменилось.
Офлайн
Ну ладно… Вот тебе полный вариант.
import sys from PyQt4 import QtGui, QtCore class Example(QtGui.QWidget): def __init__(self): super(Example, self).__init__() self.initUI() self.inFocus = ('', '') # Элемент (и его данные), который последним был в фокусе def initUI(self): self.setGeometry(300, 300, 280, 170) self.setWindowTitle('Hello!') self.a = QtGui.QLineEdit(self) self.a.installEventFilter(self) self.a.move(60, 50) self.a.setFocus() self.b = QSelectPath(self) self.b.setFocusPolicy(QtCore.Qt.StrongFocus) self.b.installEventFilter(self) self.b.move(60, 100) def eventFilter(self, obj, event): if obj == self.inFocus[0]: if event.type() == QtCore.QEvent.FocusOut: print('Фокус потерян') else: if event.type() == QtCore.QEvent.FocusIn: self.inFocus = (obj, obj.text()) print('В фокусе') return False class QSelectPath(QtGui.QWidget): """ Виджет для выбора пути к папке """ def __init__(self, parent=None): super(QSelectPath, self).__init__(parent) self.buildWidget() def buildWidget(self): mainLayout = QtGui.QHBoxLayout() mainLayout.setContentsMargins(0, 0, 0, 0) # Убираем внешние отступы у компановщика self.path = QtGui.QLineEdit(self) self.path.setReadOnly(True) self.path.setFocusPolicy(QtCore.Qt.NoFocus) overview = QtGui.QPushButton('Обзор', self) overview.setFocusPolicy(QtCore.Qt.NoFocus) self.connect(overview, QtCore.SIGNAL('clicked()'), self.chooseFile) mainLayout.addWidget(self.path) mainLayout.addWidget(overview) self.setLayout(mainLayout) def chooseFile(self): """ Открывает диалоговое окно выбора папки """ path = QtGui.QFileDialog.getExistingDirectory(self, 'Выберите папку') if path: self.path.setText(path) def text(self): return self.path.text() def setText(self, string): self.path.setText(string) if __name__ == '__main__': app = QtGui.QApplication(sys.argv) window = Example() window.show() sys.exit(app.exec_())
Офлайн
Во, вот так уже работает. Спасибо!
Офлайн
Дабы не плодить темы.
Есть окно QWidget, в нём разные элементы (поля, кнопки и т.д.). По умолчанию при запуске программы становится активным самый первый элемент. Захотел изменить ситууацию, перевести фокус на нужное мне поле, например, self.pole_2. Прописал вот так:
self.pole_2 = QLineEdit() self.pole_2.setFocus()
self.pole_2 = QLineEdit(self)
Офлайн
Если в окне на какой-то кнопке будет установлен setAutoDefault(True), то фокус автоматически установится на эту кнопку, тогда на первый элемент фокус нужно будет установить принудительно, а так автоматически устанавливается фокус на первого потомка, которому в принципе можно установить фокус. Вы указали родителя своему первому элементу, окно стало знать, кому установить фокус. Еще, если в окне есть стандартные кнопки QButtonBox, то фокус автоматически установится на первую кнопку в этом боксе.
Офлайн
А как здесь передать фокус полю 1?
# Python 3 # -*- coding: utf-8 -*- import sys from PyQt4 import QtCore, QtGui from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout, QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox, QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy, QGroupBox) from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor from PyQt4.QtCore import QSize # ЦВЕТА ПОЛЕЙ sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 14pt 'Courier New'") # ГРАФИКА class Window(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.resize(200, 200) # шир / выс окна self.setWindowTitle('Заголовок') # Заголовок # БЛОК РАЗМЕТКИ vbox = QVBoxLayout() vbox_1 = QVBoxLayout() # --- --- viewport_1 = QWidget() viewport_1.setLayout(vbox_1) self.pole_1 = QLineEdit(self) self.pole_1.setFocus() vbox_1.addWidget(self.pole_1) # --- self.pole_2 = QLineEdit() vbox_1.addWidget(self.pole_2) viewport_2 = QWidget() # --- --- self.tab = QTabWidget() self.tab.addTab(viewport_1, 'Вкладка 1') self.tab.addTab(viewport_2, 'Вкладка 2') vbox.addWidget(self.tab) # --- self.setLayout(vbox) # КОНЕЦ if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
Отредактировано Kyrym (Янв. 17, 2018 22:28:22)
Офлайн
Kyrymта также идем и ичтаем сначала документацию, http://doc.crossplatform.ru/qt/4.8.x/html-qt/qwidget.html#setFocus
А как здесь передать фокус полю 1?
Gives the keyboard input focus to this widget (or its focus proxy) if this widget or one of its parents is the active windowвот в таком виже работает:
перевод:
Дает фокус ввода с клавиатуры для этого виджета (или его фокус-прокси), если этот виджет или один из его родителей является активным окном
# Python 3 # -*- coding: utf-8 -*- import sys from PyQt4 import QtCore, QtGui from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout, QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox, QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy, QGroupBox) from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor from PyQt4.QtCore import QSize # ЦВЕТА ПОЛЕЙ sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 14pt 'Courier New'") # ГРАФИКА class Window(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.resize(200, 200) # шир / выс окна self.setWindowTitle('Заголовок') # Заголовок # БЛОК РАЗМЕТКИ vbox = QVBoxLayout() vbox_1 = QVBoxLayout() # --- --- viewport_1 = QWidget(self) viewport_1.setLayout(vbox_1) self.pole_1 = QLineEdit(self) self.pole_1.setFocus() vbox_1.addWidget(self.pole_1) # --- self.pole_2 = QLineEdit() vbox_1.addWidget(self.pole_2) viewport_2 = QWidget() # --- --- self.tab = QTabWidget(self) self.tab.addTab(viewport_1, 'Вкладка 1') self.tab.addTab(viewport_2, 'Вкладка 2') vbox.addWidget(self.tab) # --- self.setLayout(vbox) # КОНЕЦ if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
[code python][/code]
Офлайн
Во вьюпорт я пробовал ставить self, а в QTabWidget - нет.
Офлайн