Получить указатель на QTextBlock в QPlainTextEdit

Я хочу сопоставить два указателя в объекте QMap, чтобы сохранить их отношение. Указатель ключа указывает на QTextBlock, а указатель значения указывает на виджет. Цель состоит в том, чтобы обновить позицию виджета относительно позиции QTextBlock в QPlainTextEdit, когда что-то в QPlainTextEdit изменяется. Виджет должен быть уничтожен, когда будет уничтожен QTextBlock.

Однако я не знаком с поведением QTextBlock в QPlainTextEdit. Хотя метод firstVisibleBlock() не возвращает указатель на QTextBlock в QPlainTextEdit, я создаю новый QTextBlock с QTextBlock из QPlainTextEdit в качестве параметра.

QTextBlock* CodeEditor::getBlockAtPosition(QPoint position) {

  QTextBlock block = firstVisibleBlock();
  while (true)
    {
      QRectF blockDim = blockBoundingGeometry(block).translated(contentOffset());
      if (position.y() <= blockDim.bottom() && position.y() >= blockDim.top())
        {
          break;
        }
      else if (block.blockNumber() + 1 < blockCount())
        block = block.next();
      else break;
    }
  return new QTextBlock (block);
}

Кажется, это работает, потому что, когда я добавляю новые строки (QTextBlocks) в QPlainTextEdit, нажимая Enter/Return, атрибуты объекта за указателем изменяются, как предполагалось. Это означает, что если вы вставите строку перед соответствующим блоком, номер блока увеличится, а геометрия/положение изменится.

Но если вы удалите соответствующую строку (backspace/del), указатель по-прежнему указывает на QTextBlock в QPlainTextEdit - я понятия не имею, как и почему. Когда я вызываю метод isValid() для значения указателя, он возвращает true.

Итак, почему атрибуты меняются, хотя это новый объект QTextBlock? Есть ли способ получить прямой указатель или ссылку на QTextBlock в QPlainTextEdit?


person Ben    schedule 01.12.2011    source источник
comment
Вы пытались вставитьText() в оборванный QTextBlock? Вы проверили свойство QTextBlock::isVisible?   -  person ibizaman    schedule 17.07.2013


Ответы (1)


Я знаю, что это старый вопрос, но я наткнулся на него, ища решение аналогичной проблемы, поэтому я отвечаю, чтобы задокументировать то, что я нашел, что может иметь отношение к будущим поискам.

Я пытался прикрепить какой-то внешний маркер для привязки к определенной строке, даже когда редактирование вставляет/удаляет другие строки. Проблема заключалась в том, что даже если линия, прикрепленная к маркеру, была удалена, блочный объект использовался повторно, и поэтому маркер перемещался в неправильное положение.

Решение заключалось в использовании функции пользовательских данных текстового блока. Когда блок «удаляется» и используется повторно, пользовательские данные удаляются. Итак, мой маркер наследуется от QTextBlockUserData, и я устанавливаю маркер в качестве пользовательских данных для блока и сохраняю ссылку на блок в маркере. Затем проверка достоверности заключается в простом сравнении объекта-маркера и пользовательских данных, хранящихся в блоке. Кажется, работает.

person Photon    schedule 17.01.2016