Seite 1 von 1

[gelöst] QTextEdit mit Zeilennummern (QT3)

Verfasst: 14. Januar 2011 08:38
von whit3
Hallo, ich habe zwar schon viel gefunden, aber alles nur für QT 4 ... und da ich nicht der beste Programmierer bin... bräuchte ich vllt ein Lösungsansatz.
mit

Code: Alles auswählen

QTextEdit::setMargins(20,0,0,0); 
kann man sich ja Platz schaffen.
Dann würde ich sagen, man zeichnet einfach ein QWidget darüber, welches die Maße des geschaffenen Bereiches hat (wie ermittle ich diese :?: ).

Ich weiß dass dies vllt. schon oft behandelt wurde, aber ich habe wirklich nichts gefunden, was mich weiter brachte :( ..

Verfasst: 14. Januar 2011 09:06
von upsala
Warum kannst du keine neuere Qt-Version verwenden?

Verfasst: 14. Januar 2011 09:17
von whit3
weil wir keine Lizenz haben :cry:

Verfasst: 17. Januar 2011 10:59
von brax
Ihr könnt Qt auch unter der LGPL benutzen. Such mal im Forum nach "Lizenz", da gibt es viele Threads zu. Z.B. den hier: http://www.qtforum.de/forum/viewtopic.php?t=13057

Verfasst: 30. März 2011 13:19
von whit3
Brauche leider ne Lösung in 3.3.6...

hab mich jetzt an diesem Beispiel aus dem Forum orientiert.
http://qtforum.de/forum/viewtopic.php?t ... lennummern

Und meinen Code so angepasst:

Code: Alles auswählen

bool CodeEditor::event(QEvent* event)
{
	if (event->type()==QEvent::Paint) 
	{
		QPainter p(this);
		p.fillRect(0, 0, 50, height(), QColor(212, 208, 202));
	      
		const QFontMetrics fm = fontMetrics(); 
		const int ascent = fontMetrics().ascent()+2;
		for(int m_lineNumber(1);m_lineNumber<paragraphs();m_lineNumber++)
		{
			const QString txt = QString::number(m_lineNumber);
			p.drawText(paragraphRect(m_lineNumber).x(),paragraphRect(m_lineNumber).y()+ascent,txt);
		}
	}
    
    return QTextEdit::event(event);
}
Jetzt habe ich allerdings das Problem, dass wenn gescrollt wird nicht neu gezeichnet wird...

Verfasst: 30. März 2011 13:28
von franzf
Man sollte sich halt die Doku durchlesen:
void QAbstractScrollArea::paintEvent ( QPaintEvent * event ) [virtual protected]
Reimplemented from QWidget::paintEvent().
This event handler can be reimplemented in a subclass to receive paint events (passed in event), for the viewport() widget.
Note: If you open a painter, make sure to open it on the viewport().
// edit:
Sry, will nicht in meinen Kopf rein, dass du unter Qt3 unterwegs bist...
Aber auch hier hat man eine ScrollView mit viewport. Dort gibt es dann QScrollView::drawContents() und QScrollView::viewportPaintEvent().
http://doc.qt.nokia.com/3.3/qscrollview.html

Verfasst: 30. März 2011 13:55
von whit3
franzf hat geschrieben:Man sollte sich halt die Doku durchlesen:
void QAbstractScrollArea::paintEvent ( QPaintEvent * event ) [virtual protected]
Reimplemented from QWidget::paintEvent().
This event handler can be reimplemented in a subclass to receive paint events (passed in event), for the viewport() widget.
Note: If you open a painter, make sure to open it on the viewport().
// edit:
Sry, will nicht in meinen Kopf rein, dass du unter Qt3 unterwegs bist...
Aber auch hier hat man eine ScrollView mit viewport. Dort gibt es dann QScrollView::drawContents() und QScrollView::viewportPaintEvent().
http://doc.qt.nokia.com/3.3/qscrollview.html
:D, glaube mir in meinen auch nicht....

Hab mir das mal angeschaut... leider komme ich nicht darauf, wie mir das helfen kann :/

Verfasst: 30. März 2011 15:15
von franzf
Im Moment zeichnest du direkt auf dem QTextEdit-Oberfläche (// edit: sry, tust du nicht, du legst einfach ein Widget irgendwo hin :D). Ein QTextEdit erbt von QAbstractScrollArea, die wiederum von QFrame. Der Frame ist das "außenrum", die ScrollArea für ScrollBars hinzu. Der eigentliche Inhalt (das Widget, auf dem der Text gemalt wird) liegt auf einem separaten Widget, dem viewport. Das paintEvent der ScrollArea mappt jenes auf den viewport, abhängig von der eigenen Größe, der Position der ScrollBars usw.
Wenn du selber etwas dazumalen willst, sollst du nun auf den viewport malen. Du willst ja, dass die Zeilennummern zum Inhalt passen, deshalb musst du das auch dort malen wo der Inhalt gemalt wird (grob).

Verfasst: 31. März 2011 12:22
von whit3
Danke für deine Antwort franzf!
Aber ich blicke da nicht wirklich durch, was wohl an mir liegt und nicht an deiner Erklärung!

hab es mal so versucht, weil du geschrieben hast, ich solle auf den viewport zeichnen... aber das ändert nichts... ich steh voll auf dem Schlauch :cry:

Code: Alles auswählen

bool CodeEditor::event(QEvent* event)
{
	if (event->type()==QEvent::Paint) 
	{
	QPainter p(this->viewport());
		p.fillRect(0, 0, 50, height(), QColor(212, 208, 202));
	      
		const QFontMetrics fm = fontMetrics(); 
		const int ascent = fontMetrics().ascent()+2;
		for(int m_lineNumber(0);m_lineNumber<paragraphs();m_lineNumber++)
		{
			const QString txt = QString::number(m_lineNumber).append(":");
			p.drawText(50-fm.width(txt)-2,paragraphRect(m_lineNumber).y()+ascent,txt); //50 WEGEN MARGIN
		}
	}
    
    return QTextEdit::event(event);
}



Verfasst: 31. März 2011 14:09
von franzf
Nimm doch dann mal viewportPaintEvent() oder drawContents() (das sollst du implementieren und dort deine Zeichnungen durchführen).

Verfasst: 1. April 2011 12:55
von whit3
habe es jetzt anders gemacht, hier mal die Lösung, für alle die es brauchen:

Code: Alles auswählen

CodeEditor::CodeEditor(QWidget *parent) : QTextEdit(parent)
{
	.....
	linenumbers = new QTextEdit(this);
	linenumbers->hide();
	linenumbers->setVScrollBarMode(QScrollView::AlwaysOff);
	linenumbers->setHScrollBarMode(QScrollView::AlwaysOff);
	linenumbers->setReadOnly(true);
	linenumbers->insertAt("1",0,0);
	linenumbers->setFrameStyle(QFrame::TabWidgetPanel | QFrame::Sunken);
	linenumbers->setBackgroundColor(QColor(0,0,0));
	linenumbers->show();

	loadedLines=false;

	connect(this, SIGNAL(contentsMoving(int,int)),linenumbers,SLOT(setContentsPos(int,int)));
	connect(this, SIGNAL(textChanged()), this, SLOT(slot_updateLinenumbers()));
}

void CodeEditor::loadLinenumbers()
{
	for(int i=0; i < paragraphs(); i++)
	{	
		linenumbers->setParagraphBackgroundColor(0,QColor(212, 208, 202));
		linenumbers->insertParagraph(QString::number(i+1),i);
	}	
	linenumbers->removeParagraph(linenumbers->paragraphs()-1);
	loadedLines=true;
}

void CodeEditor::slot_updateLinenumbers()
{
	if(loadedLines)
	{
		if(this->paragraphs() > linenumbers->paragraphs())									
		{	
			linenumbers->hide();
			for(int i=linenumbers->paragraphs() ;i<paragraphs();i++)
			{
				linenumbers->insertParagraph(QString::number(linenumbers->paragraphs()+1),linenumbers->paragraphs()); 
			}
			linenumbers->removeParagraph(linenumbers->paragraphs()-1);
			linenumbers->show();
		}
		if(this->paragraphs() < linenumbers->paragraphs())									
		{
			linenumbers->hide();
			for(int i=linenumbers->paragraphs(); i>=paragraphs(); i--)
			{
				linenumbers->removeParagraph(i);	
			}
			linenumbers->show();
		}
	}
}