Я написал исполняемый пример - вы можете его протестировать. Когда вы запустите эту программу, вы получите три QPushButton() -объекты и один QLineEdit() -объект. Там вы можете установить или удалить/удалить фильтр событий или закрыть приложение. Установите фильтр событий и введите текст. Вы увидите то, что я хочу. Я хочу, чтобы программа примера защищала пробел. В этой текущей версии пользователь не может нажать клавишу пробела более 2 раз. Эта программа работает.PyQt 4. Я не могу удалить содержимое QLineEdit() - object
Но У меня есть небольшая проблема. Когда я пишу текст в QLineEdit() -объект, а затем выделяю текст и нажимаю клавишу «Удалить» или «Возвращать», ничего не происходит. Я не могу удалить текст. Я также не могу скопировать выделенный текст.
Неправильный код внизу?
#!/usr/bin/env python
import sys
from PyQt4.QtCore import QEvent, Qt
from PyQt4.QtGui import QMainWindow, QWidget, QApplication, QVBoxLayout, QLineEdit, QPushButton
class Window(QMainWindow):
def __init__(self, parent=None):
QMainWindow.__init__(self, parent)
self.count_space_pressed = 0
self.current_pos = None
self.init_ui()
self.init_signal_slot_push_button()
def init_ui(self):
centralwidget = QWidget(self)
self.input_line_edit = QLineEdit(self)
self.close_push = QPushButton(self)
self.close_push.setEnabled(False)
self.close_push.setText("Close")
self.push_install = QPushButton(self)
self.push_install.setText("Install eventFilter")
self.push_deinstall = QPushButton(self)
self.push_deinstall.setText("Deinstall eventFilter")
layout = QVBoxLayout(centralwidget)
layout.addWidget(self.input_line_edit)
layout.addWidget(self.push_install)
layout.addWidget(self.push_deinstall)
layout.addWidget(self.close_push)
self.setCentralWidget(centralwidget)
return
def install_filter_event(self, widget_object):
widget_object.installEventFilter(self)
return
def deinstall_filter_event(self, widget_object):
widget_object.removeEventFilter(self)
return
def init_signal_slot_push_button(self):
self.close_push.clicked.connect(self.close)
self.push_install.clicked.connect(lambda: self.install_filter_event(self.input_line_edit))
self.push_deinstall.clicked.connect(lambda: self.deinstall_filter_event(self.input_line_edit))
return
def strip_string(self, content, site=None):
if site == "right":
return content.rstrip()
elif site == "right_left":
return content.strip()
elif site == "left":
return content.lstrip()
def eventFilter(self, received_object, event):
content_line_edit = unicode(received_object.text())
if event.type() == QEvent.KeyPress:
if event.key() == Qt.Key_Space:
'''
Yes, the user did press the Space-Key. We
count how often he pressed the space key.
'''
self.count_space_pressed = self.count_space_pressed + 1
if int(self.count_space_pressed) > 1:
'''
The user did press the space key more than 1 time.
'''
self.close_push.setEnabled(False)
'''
Now we know the user did press the
space key more than 1 time. We take a look,
if variablenamed (sel.current_pos) is None.
That means, no current position is saved.
'''
if self.current_pos is None:
'''
Well no current position is saved,
that why we save the new position anf
then we set the position of the cursor.
'''
self.current_pos = received_object.cursorPosition()
received_object.setCursorPosition(int(self.current_pos))
received_object.clear()
received_object.setText(self.strip_string(content_line_edit, site="right"))
else:
'''
Well the user press the space key again, for
example 3, 4, 5, 6 times we want to keep the
old position of the cursor until he press
no space key.
'''
received_object.setCursorPosition(int(self.current_pos))
'''
We have to remove all spaces in a string
on the right side and set the content on QLineEdit-widget.
'''
received_object.clear()
received_object.setText(self.strip_string(content_line_edit, site="right"))
else: pass
else:
'''
No the user didn't press the space key.
So we set all setting on default.
'''
self.close_push.setEnabled(True)
self.current_pos = None
self.count_space_pressed = 0
received_object.clear()
received_object.setText(self.strip_string(content_line_edit, site="left"))
# Call Base Class Method to Continue Normal Event Processing
return QMainWindow.eventFilter(self, received_object, event)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = Window()
window.show()
app.exec_()
EDIT:
import sys, re
from PyQt4 import QtCore, QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
self.edit = QtGui.QLineEdit(self)
self.edit.textChanged.connect(self.handleTextChanged)
layout = QtGui.QVBoxLayout(self)
layout.addWidget(self.edit)
# First we save the the regular expression pattern
# in a variable named regex.
#@ This means: one whitespace character, followed by
#@ one or more whitespaces chatacters
regex = r"\s\s+"
# Now we comple the pattern.
# After then we save the compiled patter
# as result in a variable named compiled_re.
self.compiled_re = re.compile(regex)
def handleTextChanged(self, text):
# When the text of a widget-object is changed,
# we do something.
# Here I am really not sure.
# Do you want to look if the given text isn't empty?
#@ No, we want to search the string to see if it
#@ contains any runs of multiple spaces
if self.compiled_re.search(text):
# We know that given text is a QString-object.
# So we have to convert the given text
# into a python-string, because we want to work
# with them in python.
text = unicode(text)
# NOTICE: Do replacements before and after cursor pos
# We save the current and correct cursor position
# of a QLineEdit()-object in the variable named pos.
pos = self.edit.cursorPosition()
# Search and Replace: Here the sub()-method
# replaces all occurrences of the RE pattern
# in string with text.
# And then it returns modified string and saves
# it in the variables prefix and suffix.
# BUT I am not sure If I understand this: [:pos]
# and [pos:]. I will try to understnand.
# I think we are talking about slicing, right?
# And I think the slicing works like string[start:end]:
# So text[:pos] means, search and replace all whitesapce
# at the end of the text-string. And the same again, but
# text[pos:] means, search and replace all whitesapce
# at the start of the string-text.
#@ Right, but the wrong way round. text[:pos] means from
#@ the start of the string up to pos (the prefix); and
#@ text[pos:] means from pos up to the end of the string
#@ (the suffix)
prefix = self.compiled_re.sub(' ', text[:pos])
suffix = self.compiled_re.sub(' ', text[pos:])
# NOTICE: Cursor might be between spaces
# Now we take a look if the variable prefix ends
# with a whitespace and we check if suffix starts
# with a whitespace.
# BUT, why we do that?
#@ Imagine that the string is "A |B C" (with the cursor
#@ shown as "|"). If "B" is deleted, we will get "A | C"
#@ with the cursor left between multiple spaces. But
#@ when the string is split into prefix and suffix,
#@ each part will contain only *one* space, so the
#@ regexp won't replace them.
if prefix.endswith(' ') and suffix.startswith(' '):
# Yes its True, so we overwrite the variable named
# suffix and slice it. suffix[1:] means, we starts
# at 1 until open end.
#@ This removes the extra space at the start of the
#@ suffix that was missed by the regexp (see above)
suffix = suffix[1:]
# Now we have to set the text of the QLineEdit()-object,
# so we put the both varialbes named prefix and suffix
# together.
self.edit.setText(prefix + suffix)
# After then, we have to set the cursor position.
# I know that the len()-method returns the length of the
# variable named prefix.
# BUT why we have to do that?
#@ When the text is set, it will clear the cursor. The
#@ prefix and suffix gives the text before and after the
#@ old cursor position. Removing spaces may have shifted
#@ the old position, so the new postion is calculated
#@ from the length of the current prefix
self.edit.setCursorPosition(len(prefix))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Window()
window.setGeometry(500, 150, 300, 100)
window.show()
sys.exit(app.exec_())
EDIT 2:
Два вопроса:
Первый вопрос: в if.condition, где мы посмотрим если префикс заканчивается, а суффикс начинается с sapces, то мы являемся чтобы удалить дополнительное пространство в начале суффикса. Но почему бы нам не удалить лишнее пространство при запуске префикса? Представьте себе: пользователь вводит «Префикс и суффикс» - с дополнительными пробелами в начале и конце. Не нужно ли нам удалять лишнее пространство при запуске префикса - например: prefix= prefix[:1]
?
Второй вопрос: В конце handleTextChanged() -метода, мы должны вычислить новое положение курсора. В текущем случае мы используем префикс для получения длины строки. Почему не len из нового измененного текста, который является частью префикса и суффикса? Пример: старая строка - «Префикс и суффикс», пользователь удаляет слово «и». Теперь наша строка выглядит как «Префикс | Суффикс»После того, как все пробельные символы будут удалены, мы получим новый измененный текст:„. Префикс Суффикс“Почему мы не вычисляем новое положение из измененного текста Или я что-то пропустил
EDIT 3:?
Я извиняюсь, я до сих пор не понимаю ситуацию
Первая ситуация: Когда пользователь печатает следующую строку:.. «A B C |
» (| показано, как курсор) Теперь пользователь нажимает пробел более 2 раз, мы получаем префикс, который содержит «A B C |
» - и никакого суффикса. И в настоящее время l ength of prexis - 6 - суффикс не имеет длины, потому что его пустой. И все слово - длина 6. Текущее положение курсора - 7.
Вторая ситуация: Пользовательский тип «A B D E F |
». И теперь он понимает, что письмо отсутствует: C
.Он перемещает курсор назад между B
и D
и типы C
, а затем он собирается нажать клавишу пробела 2 раза. Теперь у нас есть префикс, который содержит «A B C
» и суффикс, содержимое которого «D E F
». Длина префикса равна 6, а суффикса - 5. Длина всего слова равна 11. И в этот момент текущая позиция курсора равна 7. В этой ситуации вы берете длину префикса и устанавливаете позицию курсора, вправо ?
Ваш демо является очень полезным и полезным. Я должен администратор. Я начинаю Python. Именно по этой причине я анализирую ваш код. Я хочу все понять. Я редактировал свой первый вопрос. Я написал свои мысли и вопросы в код как комментарии. Я попытался убрать тебя. В этих комментариях вы увидите мою проблему с пониманием, и вы также увидите, правильно ли я вас понял. – Sophus
@Sophus. Я добавил несколько комментариев к вашему новому коду (все они начинаются с '# @'). – ekhumoro
Спасибо. Есть еще одна проблема понимания. Я написал в своем приветственном вопросе под заголовком «EDIT 2:» – Sophus