2013-09-26 39 views
5

Chcę utworzyć aplikację z dwoma głównymi widgetami, jednym z nich jest edytor tekstu, a drugi dla przeglądarki graficznej.Jak utworzyć interaktywny widget edycji tekstu Qt?

enter image description here

Podstawowym założeniem jest to, aby pozwolić unosić użytkownik w dowolnym bloku kodu w polu tekstowym i związanego z części rysunku zostanie wybrany lub zaznaczony.

Dla widżetu graficznego, po niektórych badaniach wydaje się, że QGraphicsScene najbardziej odpowiada wymaganiom, ale nie jestem pewien, jakiego widgetu użyć w edytorze tekstu, tak, że daje mi sygnał po najechaniu kursorem na dowolny blok kodu (a także wysłać parametr łańcuchowy "id" bloku).

Potrzebne jest również działanie odwrotne, więc gdy użytkownik wybierze inspekcję elementu w widoku graficznym, widok tekstu jest przewijany, aby wyświetlić skojarzony blok kodu i podświetlić go (podobnie jak w przeglądarce Google Chrome "Sprawdź element").

+2

pan spróbować z redefinicji 'mouseMoveEvent' w klasie pochodnej z widgetami w którym chcesz wykryć najechania kursorem? – Tab

+1

Nie używałbym osobiście QGraphicsScene do tego, ale raczej qml lub przynajmniej opartego na OpenGL rozwiązania z QtGui dla przeglądarki graficznej. W widgecie tekstu można uzyskać pozycję kursora, ale niestety jest to dość trudne. Jednak rzeczywiście wyglądałoby to fantazyjną cechą IMO. :-) – lpapp

+1

@Tab problem, ponieważ rozumiem, że op jeszcze się nie zdecydował, z której klasy wywodzić – Shf

Odpowiedz

2

Aby podświetlić tekst, gdy obiekt jest zawieszony w scenie, należy ponownie zaimplementować QGraphicsScene i QGraphicsItem (którego należy użyć), aby poinformować mainwindow, aby znaleźć i zaznaczyć tekst.Oto przykładowy kod, aby podświetlić tekst, gdy obiekt unosił się w miejscu użyłem QGraphicsPixmapItem:


Graphic scena

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); 
} 

w MainWindow konstruktor podłącz

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

Oto gniazdo:

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); 
} 

i logika rysować:

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; 

UWAGA: Korzystanie EmitItemHoverd publicznego może być problem tutaj użyłem tylko przez wzgląd na wyjaśnienia logiki ty może uczynić go chronionym wymaganymi zmianami.

Tak Wiedziałem swoją połowę odpowiedź lecz przeciwnie logika może być implimented na podstawie wyżej

+1

Dzięki Zakładka dla tej odpowiedzi :) Pomysł nadrzędnymi sygnał aktywowania z QGraphicsScene jest całkiem dobry, będę absolutnie rozważyć to. –

+0

Btw, „TextEdit” nie obsługuje wiele fantazyjnych funkcje edycji tekstu (jak: numeracja linii, linia kolorowania „nieparzyste linie mają inny kolor tła niż nawet wierszy”, Kolor automatyczny słowa kluczowe, ...) ciągle szukam w celu obejścia tych problemów. PS: Twoja Funkcja "OnItemHovered" będzie działać lepiej, jeśli dodać tę linię na początku: ui-> textEdit-> moveCursor (QTextCursor :: Start); ponieważ teraz nie może znaleźć bloku w kodzie, jeśli blok leży przed bieżącą pozycją kursora. –

+0

Edycja tekstu obsługuje skrypt html, dzięki czemu można zarządzać tym arkuszem stylów. W przypadku QTextCursor nie testowałem tego kodu tak bardzo, że próbowałem tylko sprawdzić, czy mój pomysł jest możliwy do zrealizowania, czy też nie, dzięki za sugestię. – Tab

4

Można użyć QTextEdit::cursorForPosition i QTextCursor::position do konwersji współrzędnych myszy na pozycję w tekście. Możesz określić ukryty blok kodu używając tej pozycji.

Możesz wybrać dowolny blok kodu w edycji tekstu zgodnie z opisem w this answer.

QGraphicsScene wydaje się być dobrym wyborem, ponieważ zawiera wszystkie funkcje, których możesz potrzebować.

1

Spróbowałbym tego całkowicie w QML. Uczyniłbym edytor tekstu listą obszarów tekstowych (prawdopodobnie tworzących nowy element QML dla pożądanego formatowania). Każda pozycja na liście jest faktycznie nowo utworzonym elementem QML (odpowiednim do zrzucenia do pliku .qml i odniesienia w wyższej pozycji). W tym momencie możesz wstrzyknąć każdy z tych elementów do widoku QML po lewej stronie, dodając jedynie obsługę myszy do uruchamiania po najechaniu kursorem myszy lub kliknięciu w tym obszarze.

Lewą stroną jest scena QML zarządzana i aktualizowana przez kontrolera, który pobiera surowy tekst z listy pozycji po prawej stronie i próbuje go przeanalizować jako nowy typ QML. Powinno działać, zgodnie z teorią w mojej głowie, i zmniejszyłoby to znaczną złożoność (szczególnie podczas mapowania punktu myszy bezpośrednio w tekście tekstu).

+0

Idea wielu obszarów tekstowych wydaje się być bardzo dobra na odwzorowaniu wskaźnika myszy, obawiam się, że może nie być najlepszym rozwiązaniem, ponieważ jest to edytor tekstu, aby użytkownik mógł później edytować, co oznacza wyobrazić sobie scenariusz powyższego zrzutu ekranu, a użytkownik zdecydował się później dodać nowy kształt pomiędzy dwoma blokami, w jaki sposób program może to wykryć i utworzyć nowy obszar tekstowy? ale podoba mi się to rozwiązanie i spróbuję znaleźć pracę związaną z tym problemem, dzięki :) –

+1

Czy możesz skondensować listę do pojedynczego pliku tekstowego przy zapisywaniu i rozwinąć go przy obciążeniu zgodnie z zakresami najwyższego poziomu? To byłoby całkiem fajne. – Thadeux