[gelöst] QTextEdit mit Zeilennummern (QT3)

Alles rund um die Programmierung mit Qt
Antworten
whit3
Beiträge: 42
Registriert: 1. Februar 2010 09:55

[gelöst] QTextEdit mit Zeilennummern (QT3)

Beitrag 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 :( ..
Zuletzt geändert von whit3 am 1. April 2011 12:53, insgesamt 1-mal geändert.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Warum kannst du keine neuere Qt-Version verwenden?
whit3
Beiträge: 42
Registriert: 1. Februar 2010 09:55

Beitrag von whit3 »

weil wir keine Lizenz haben :cry:
brax
Beiträge: 208
Registriert: 11. Mai 2010 11:22

Beitrag 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
whit3
Beiträge: 42
Registriert: 1. Februar 2010 09:55

Beitrag 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...
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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
whit3
Beiträge: 42
Registriert: 1. Februar 2010 09:55

Beitrag 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 :/
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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).
whit3
Beiträge: 42
Registriert: 1. Februar 2010 09:55

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


franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Nimm doch dann mal viewportPaintEvent() oder drawContents() (das sollst du implementieren und dort deine Zeichnungen durchführen).
whit3
Beiträge: 42
Registriert: 1. Februar 2010 09:55

Beitrag 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();
		}
	}
}
Antworten