2013-09-26 6 views
5

Ich möchte eine Anwendung mit zwei Haupt-Widgets entwickeln, von denen eines ein Texteditor und das andere ein Grafikbetrachter ist.Wie man ein Qt interaktives Textbearbeitungs-Widget erstellt

enter image description here

Die Grundidee ist der Benutzer schwebt über jeden Codeblock im Textbereich und der damit verbundenen Teil der Zeichnung lassen wird ausgewählt oder hervorgehoben.

Für das Grafik-Widget scheint QGraphicsScene nach einigen Recherchen den Anforderungen am besten zu entsprechen, aber ich bin mir nicht sicher, welches Widget für den Texteditor verwendet wird, damit es ein Signal gibt, wenn ich über irgendeinen Codeblock schwebe (und senden Sie auch einen String-Parameter "ID" des Blocks).

Die umgekehrte Aktion ist ebenfalls erforderlich. Wenn der Benutzer das Element in der Grafikansicht prüft, wird in der Textansicht gescrollt, um den zugeordneten Codeblock anzuzeigen und zu markieren (wie in der Google Chrome-Funktion "Element prüfen").

+2

haben Sie versucht? – Tab

+1

Ich würde QGraphicsScene dafür nicht selbst verwenden, sondern eher qml oder zumindest opengl basierte Lösung mit QtGui für den Grafikbetrachter. Sie könnten die Position des Cursors irgendwie im Text-Widget finden, aber leider ist das ein wenig schwierig. Allerdings würde dies in der Tat ein schickes Feature IMO aussehen. :-) – lpapp

+1

@Tab das Problem, wie ich verstehe ist, dass op noch nicht entschieden hat, aus welcher Klasse – Shf

Antwort

2

Um Text hervorzuheben, wenn ein Objekt in der Szene schwebt, müssen Sie QGraphicsScene und QGraphicsItem (welches Sie verwenden) neu implementieren, um Hauptfenster zu informieren, um Text zu finden und hervorzuheben.Hier ist Beispielcode Text zu markieren, wenn ein Objekt in Szene schwebte ich verwendet QGraphicsPixmapItem:


Grafik-Szene

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

in Mainwindow Konstruktor verbinden

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

Hier Slot:

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

und Logik zu zeichnen:

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; 

HINWEIS: public EmitItemHoverd Verwendung ein Problem sein kann, hier habe ich nur aus Gründen der Erläuterung der Logik, die Sie kann es mit den erforderlichen Änderungen schützen.

Ja wusste, dass ich seine Hälfte der Antwort, aber entgegengesetzte Logik implimented werden kann mit Neudefinition `mouseMoveEvent` in abgeleiteten Klasse des Widgets in dem Sie schweben erkennen, basierend auf über

+1

Danke Tab für diese Antwort :) Die Idee, das Schwebesignal von QGraphicsScene zu übersteuern ist ziemlich gut, ich werde das absolut berücksichtigen. –

+0

Btw, "TextEdit" unterstützt nicht viele fancy Textbearbeitungsfunktionen (wie: Zeilennummerierung, Zeilenfärbung "ungerade Zeilen haben unterschiedliche Hintergrundfarbe als gerade Zeilen", automatische Farbschlüsselwörter, ...) Ich suche immer noch für Problemumgehungen zu diesen Problemen. PS: Ihre "OnItemHovered" -Funktion wird besser funktionieren, wenn Sie diese Zeile am Anfang hinzufügen: ui-> TextEdit-> moveCursor (QTextCursor :: Start); , weil es jetzt den Block im Code nicht finden kann, wenn der Block vor der aktuellen Cursorposition liegt. –

+0

Text bearbeiten unterstützt HTML-Skript, damit Sie Stylesheet damit verwalten können. Für den QTextCursor habe ich diesen Code nicht so sehr getestet, ich habe nur versucht zu sehen, ob meine Idee implementierbar oder nicht gut ist, danke für den Vorschlag. – Tab

4

Sie können QTextEdit::cursorForPosition und QTextCursor::position verwenden, um Mauskoordinaten in Position im Text zu konvertieren. Sie können den überlebten Codeblock anhand dieser Position ermitteln.

Sie können einen beliebigen Codeblock in der Textbearbeitung auswählen, wie in this answer beschrieben.

QGraphicsScene scheint eine gute Wahl zu sein, da es alle Funktionen enthält, die Sie benötigen.

1

Ich würde dies vollständig in QML versuchen. Ich würde den Texteditor eine Liste von Textbereichen machen (möglicherweise ein neues QML-Element für die gewünschte Formatierung erstellen). Jedes Element in der Liste ist effektiv ein neu erstelltes QML-Element selbst (das geeignet ist, in eine .qml-Datei ausgegeben und in einem höheren Element referenziert zu werden). An dieser Stelle können Sie jedes dieser Elemente in die QML-Ansicht auf der linken Seite injizieren, indem Sie nur Mouse-Handler hinzufügen, die ausgelöst werden, wenn Sie den Mauszeiger über den Bereich bewegen.

Die linke Seite ist also eine QML-Szene, die von einem Controller verwaltet und aktualisiert wird, der unformatierten Text aus einer Elementliste auf der rechten Seite nimmt und versucht, ihn als neuen QML-Typ auszugeben. Es sollte nach der Theorie in meinem Kopf funktionieren, und es würde eine erhebliche Menge an Komplexität reduzieren (insbesondere beim direkten Zuordnen eines Mauspunkts in einen Textkörper).

+0

Die Idee der mehrere Textbereiche scheint sehr gut auf die Zuordnung der Maus Hover, ich fürchte, es kann nicht die beste Lösung sein, weil dies ein ist Text-Editor, so dass der Benutzer später bearbeiten kann, dh das Szenario des obigen Screenshots vorstellen, und der Benutzer entschied später, eine neue Form zwischen den beiden Blöcken hinzuzufügen, wie kann das Programm das erkennen und einen neuen Textbereich erstellen? aber ich mag diese Lösung und werde versuchen, eine Arbeit rund um dieses Problem zu finden, danke :) –

+1

Könnten Sie die Liste zu einer einzigen Textdatei beim Speichern zusammenfassen und erweitern Sie es auf Laden entsprechend der Top-Level-Bereiche? Das wäre ziemlich cool. – Thadeux