2013-09-26 5 views
5

Я хочу разработать приложение с двумя главными виджетами, одним из которых является текстовый редактор, а другой - для графического просмотра.Как создать интерактивный виджет редактирования текста Qt

enter image description here

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

Для графического виджета после некоторых исследований кажется, что QGraphicsScene соответствует требованиям больше всего, но я не уверен, какой виджет будет использоваться для текстового редактора, так что он дает мне сигнал при наведении курсора на любой блок кода (а также отправить строковый параметр «id» блока).

Требуется также обратное действие, поэтому, когда пользователь хочет проверить элемент в графическом представлении, прокручивается текстовое представление, чтобы просмотреть ассоциированный блок кода и выделить его (например, в функции Google Chrome «Проверить элемент»).

+2

вы пытались с переопределение 'mouseMoveEvent' в производном классе виджетов, в которых вы хотите обнаружить парить? – Tab

+1

Я бы лично не использовал QGraphicsScene для этого, а скорее qml или, по крайней мере, opengl-решение с QtGui для графического просмотра. Вы могли бы как-то получить положение курсора в текстовом виджете, но, к сожалению, это довольно сложно. Тем не менее, это действительно выглядело бы причудливой особенностью ИМО. :-) – lpapp

+1

@Tab проблема, как я понимаю, заключается в том, что op еще не решил, из какого класса вывести – Shf

ответ

2

Чтобы выделить текст, когда объект завис в сцене, вы должны переопределить QGraphicsScene и QGraphicsItem (какой из них вы собираетесь использовать), чтобы сообщить основному окну, чтобы найти и выделить текст.Ниже приведен пример кода для выделения текста, когда объект парил в сцене я использовал QGraphicsPixmapItem:


Графическая сцена

class GraphicScene : public QGraphicsScene 
{ 
    Q_OBJECT 
public: 
    GraphicScene(); 

    void EmitItemHoverd(QString name) 
    { 
     emit SignalItemHovered(name); 
    } 


signals: 
    void SignalItemHovered(QString); 
}; 

GraphicsItem:

#include "GraphicScene.h" 

class GraphicItem : public QGraphicsPixmapItem 
{ 
    QString itemName; 
    GraphicScene * scene; 
public: 
    GraphicItem(GraphicScene *s, QString name);//name you can set from editor 

    void hoverEnterEvent(QGraphicsSceneHoverEvent *event); 

}; 
GraphicItem::GraphicItem(GraphicScene *s, QString name) 
{ 
    scene = s; 
    itemName = name; 
    this->setAcceptHoverEvents(true); 
} 

void GraphicItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) 
{ 
    scene->EmitItemHoverd(itemName); 
} 

в MainWindow конструктор connect

connect(scene,SIGNAL(SignalItemHovered(QString)),this,SLOT(OnItemHovered(QString))); 

Вот слот:

void MainWindow::OnItemHovered(QString name) 
{ 
    ui->textEdit->find(name); 
    QTextCursor tc = ui->textEdit->textCursor(); 
    tc.select(QTextCursor::WordUnderCursor);  
    ui->textEdit->find("}"); 
    QTextCursor tc1 = ui->textEdit->textCursor(); 
    tc1.select(QTextCursor::WordUnderCursor); 
    int pos2 = tc1.selectionStart(); 

    tc.setPosition(pos2,QTextCursor::KeepAnchor); 
    ui->textEdit->setTextCursor(tc); 
} 

и логика рисовать:

GraphicItem * item = new GraphicItem(scene,"Circle"); 

    QPixmap map(50,50); 
    QPainter * painter= new QPainter(&map); 
    painter->setBrush(QBrush(Qt::red,Qt::SolidPattern)); 
    painter->drawEllipse(20,20,15,15); 
    item->setPixmap(map); 

    scene->addItem(item); 
    ui->graphicsView->update(); 
    delete painter; 

ПРИМЕЧАНИЕ: Использование публичного EmitItemHoverd может быть проблема здесь я только ради объяснения логики вам может защитить его с помощью необходимых изменений.

Да, я знал, что его половину ответа, но обратная логика может быть implimented на основе выше

+1

Спасибо за этот ответ :) Идея переопределения сигнала наведения QGraphicsScene довольно хороша, я буду абсолютно учитывать это. –

+0

Btw, «textEdit» не поддерживает множество функций редактирования текста (например, нумерация строк, окраска строк «нечетные линии имеют разный цвет фона, чем даже строки», автоматические ключевые слова цвета ...) Я все еще смотрю для обходных путей к этим вопросам. PS: ваша функция «OnItemHovered» будет работать лучше, если вы добавите эту строку в начале: ui-> textEdit-> moveCursor (QTextCursor :: Start); , потому что теперь он не может найти блок в коде, если блок лежит перед текущей позицией курсора. –

+0

текстовое редактирование поддерживает html-скрипт, поэтому вы можете управлять таблицей стилей. Для QTextCursor я так не тестировал этот код, я просто пытался понять, реализуется ли моя идея или нет, спасибо за предложение. – Tab

4

Вы можете использовать QTextEdit::cursorForPosition и QTextCursor::position, чтобы преобразовать координаты мышки в позицию в тексте. Используя эту позицию, вы можете определить наведенный код.

Вы можете выбрать произвольный код в текстовом редакторе, как описано в this answer.

QGraphicsScene представляется хорошим выбором, так как он содержит всю необходимую функциональность.

1

Я бы попытался полностью это сделать в QML. Я бы сделал текстовым редактором список текстовых областей (возможно, создав новый элемент QML для желаемого форматирования). Каждый элемент в списке фактически представляет собой недавно созданный элемент QML (подходящий для сбрасывания в файл .qml и ссылка на более высокий элемент). На этом этапе вы можете вставлять каждый из этих элементов в вид QML слева, добавляя только обработчики мыши, чтобы стрелять при наведении или щелчке по области.

Итак, левая сторона - это сцена QML, управляемая и обновляемая контроллером, который берет необработанный текст из списка элементов справа и пытается проанализировать его как новый тип QML. Он должен работать, согласно теории в моей голове, и это уменьшит значительную сложность (особенно при сопоставлении точки мыши непосредственно в тексте).

+0

Идея нескольких областей текста кажется очень хорошей при отображении мыши, я боюсь, что это может быть не лучшее решение, потому что это текстовый редактор, поэтому пользователь может редактировать позже, то есть представить себе сценарий вышеупомянутого скриншота, а позже пользователь решил добавить новую фигуру между двумя блоками, как программа может обнаружить это и создать новую текстовую область? но мне нравится это решение и попытаюсь найти работу вокруг этой проблемы, thanks :) –

+1

Не могли бы вы сконденсировать список в один текстовый файл для сохранения и развернуть его при загрузке в соответствии с областями верхнего уровня? Это было бы круто. – Thadeux

 Смежные вопросы

  • Нет связанных вопросов^_^