Click to See Complete Forum and Search --> : More Qt Questions


Dun'kalis
02-04-2003, 11:34 PM
I've got some more Qt questions.

I got my text editor working (after scrapping it and starting over), and it works fine right now.

I have two questions.

First, the QSyntaxHighlighter (I want to implement syntax highlighting) docs are really vague, and they simply tell me to reimplement highlightParagraph. I'm not sure as to how I would go about doing this.

Another question: I want to implement some sort of configuration for this program. I know it wouldn't be hard to do, but I need to know how I would search for conditions in a QTextStream object, and then emit signals based on those.

These questions probably go hand in hand...

bwkaz
02-05-2003, 11:16 AM
The best thing I can suggest for syntax highlighting is to look through the Qt source for the current state of the QSyntaxHighlighter class' highlightParagraph function. That might tell you how to do the highlighting. It may be as "simple" as adding HTML tags to the paragraph, or it may be something completely different, I don't know. I could look into it, but it'd probably take me a couple of hours, and I'm lazy. :D

For the QTextStream, I assume you've looked at the class documentation at Trolltech? Other than that... you could look at how one of the KDE programs uses it. I'm not sure which ones do, but I'd guess most of them. Maybe just something in kdebase that handles persistence for everything? I'm not quite sure.

ariell
02-05-2003, 03:48 PM
Hi there,

I'm working with Qt for more than two years. If you could specify what excatly you want a t-stream to search for I think I can get you some hints.

Best,
ariell.

Dun'kalis
02-05-2003, 05:07 PM
Wow...highlightParagraph is pretty simple. Just like the rest of Qt.

As for the text streaming, I'd want to search for stuff like "tabWidth=4" or something, simple stuff. It would then assign the found value there to a variable that controls that sort of stuff. I could do the assignment, but I can't figure out how to find the string.

AFAIK, most KDE apps use XML for comfiguration files. I don't care much for XML.

ariell
02-05-2003, 08:13 PM
Hi again,

I hope I made it readable. My suggestion: Use an "invisible" editor to handle files/streams. As for config-files, that might be a cool approach.

/*
I think using an "adapter", such as QMultiLineEdit is a very conveniant way to handle text-streams.
Once you decide to go this way, it comes in handy to derive a new class from QMultiLineEdit that
will provide additional methods to handle file contents. It's less than 100 lines of code and makes your sources
more readable.
See Trolltech's html-doc to understand QMultiLineEdit. This class really provides everything you need to
deal with lots of text stored to a single string. "Redirecting" a text stream's content to an instance of
QMultiLineEdit "eases the pain" to hook up with your file.
Hust a proposal.... Have fun.
*/

class myEditor: public QMultiLineEdit {
Q_OBJECT
public:
myEditor(QWidget * parent=0, const char * name=0); // just those args QMultiLineEdit is expecting
~myEditor();
public:
int searchKey(const char* key = 0); // checks a stream for existence of "key"
QString getKeyValue(int pos); // returns a key value from the file

};


// implementation
int myEditor::searchKey(const char* key) {
// searches current file for a certain key
// returns line number in which key was found, or (-1) if failed

if (numLines() < 1) return (-1);
int iLines = numLines()/*to avoid frequent function calls to "numLines()" when iterating*/;

// Key holds what we are looking for
QString* sCurrent = new QString("");
for (int iCurrentLine=1; iCurrentLine<iLines; iCurrentLine++) {
// move cursor to current line
setCursorPosition(iCurrentLine,1,false);
// read this line and copy to sCurrent
sCurrent = getString(iCurrentLine);
// we now have it in a regular string(-pointer)
// if key is in current line ,thus "find()" will return its position,
// -1 if not in line, exit function and return line number
if (sCurrent->find(key,0,false) > (-1)) return iCurrentLine;
}/*for*/

return (-1);
}

QString myEditor::getKeyValue(int pos) {
// reads a key-value from line pos in a text-based file and return as a QString
// if this method encounters problems it returns an empty string

QString sValue = "";
// move to line
// check for valid range
if (pos > numLines()) return sValue;
// get line content
setCursorPosition(pos,1,false);
QString* sLine = new QString(); // must be a pointer- QMultiLineEdit::getString() returns a pointer
sLine =getString(pos);
sValue = *sLine;
return sValue;
}


// example method

bool loadConfig(const char* filename) {

myEditor* ed = new myEditor(/*whatever you pass here*/);

// LOAD ed file
// construct a file-object
QFile f(filename);
if ( !f.open( IO_ReadOnly ) ) return false;

// clear editor buffer
ed->setAutoUpdate( false );
ed->clear();
// open a new stream
QTextStream t(&f);
while ( !t.eof() ) {
QString s = t.readLine();
ed->append(s);
}
// drop the file
f.close();
// re-configure editor
ed->setAutoUpdate( true );
ed->setEdited( false );
// ed file is now allocated in memory
// "invisible" editor object

bool ok = true; // as soon as there is something wrong , this value will be toggled to false

int iLineInConf = ed->searchKey("tabWidth"); // "iLineInConf" now has line number in ed file
// if ed->searchConfigKey found the appropriate entry
// value of "iLineInConf" is greater than (-1)

if (iLineInConf > (-1)) QString s = ed->getKeyValue(iLineInConf);
else ok = false;

/*
do whatever you want to do wtih "s",
split the string, search for "=" and take all that's right-handed
*/

return ok;
}

Dun'kalis
02-05-2003, 10:03 PM
/me bows.

Wow. Thats a really good idea and implementation. I was thinking of using something like QString::find(), but this is really nice.

Much better than anything I could ever come up with.

Thank you!

Energon
02-06-2003, 02:13 AM
Just out of curiosity, is there an easy way to add line numbers to a QTextEdit? I've been looking for a way but haven't come across any simple leads like I thought there would be.

ariell
02-06-2003, 04:32 AM
You're very welcome, good to know it served the purpose...

As for QTextEdit I must confess to not knowing this class. Does it come with Qt 3? If so, I can't be of any assistance, I still use Qt 2.3.

best,
ariell.

bwkaz
02-06-2003, 10:56 AM
Yes, in Qt 3, there are QLineEdit and QTextEdit widgets, where in Qt 2 (I believe) there were QLineEdit and QMultiLineEdit widgets.

I don't know if it was more than just a change in class name, though.

Energon
02-06-2003, 12:40 PM
QMultilineEdit is deprecated and inherets QTextEdit. So it's a little bit more than a name-change, but the two interfaces are a lot different.

ariell
02-06-2003, 12:44 PM
If it is, as you assume, just a change in class names, I understand QTextEdit to be substitute of QMultiLineEdit. Then, however, there is several ways to add a line. The direct approach reads something like this:

QMultiLineEdit* ed = new QmultiLineEdit(...)
QString* s = new QString("some content);
ed->append(*s); //

Consequently, they (Trolltech) should have called it QSingleLineEdit.
Anyway, thanks for your info. Qt is cool stuff, that is for sure.

Best,
ariell.

ariell
02-06-2003, 12:47 PM
append() is a void
if you need to check whether it really worked or not use:
ed->insert(ed->numLines()+1, *s);
or:
ed->insert(-1, *s)
since those methods are bool

Best,
ariell.

Dun'kalis
02-06-2003, 06:09 PM
In either the QFile or QTextStream documentation, there is a snippet of code that does just that.

Dun'kalis
02-06-2003, 11:12 PM
OK, I understand how to implement the highlightSyntax() function, but I'm getting stuck on something.

From the QTextEdit, I want to get the contents of the current paragraph (in code, most likely the current line), and then the rest of the QSyntaxHighlighter takes over.

From what I can tell, there are no functions in the QTextEdit to do that.

I also tried taking the text() property and assigning it to a QString, but it told me that the object edit (thats what the instance of QTextEdit is called) is private in this context. It is declared as public in the main window class.

Dun'kalis
02-09-2003, 12:56 AM
Some more mucking around has shown me that I don't actually need to get the paragraph myself. Very nice.

Anyway, I'm now attempting to install the syntax highlighter into my text editor, and it continues to tell me 'edit is private in this context'

Why? The QTextEdit is declared as public...

Another thing: I was looking around the Qt Designer code for their syntax highlighter, and, oddly enough...they didn't use QSyntaxHighlighter.

bwkaz
02-09-2003, 09:25 AM
"edit is private"

Hmm... Could you post the full error? And the lines of code that it's referencing (plus 5-10 lines before and after)?

Energon
02-09-2003, 01:41 PM
QT Designer doesn't use QSyntaxHighlighter because it's a new class for Qt 3.1 and QT Designer was written way back in Qt 2.

ariell
02-09-2003, 05:46 PM
First of all, I don't use Qt 3, so details are "hidden" to me.
Anyway, referencing an instance of QTextEdit as public is one thing. Using its properties or methods (that might be private from "the class' view") is quite a different thing.
Could you post some more code?

Best,
ariell.

Dun'kalis
02-09-2003, 08:15 PM
/opt/qt/include/qsyntaxhighlighter.h: In constructor `HSyntax::HSyntax()':
/opt/qt/include/qsyntaxhighlighter.h:71: `QTextEdit*QSyntaxHighlighter::edit'
is private
syntax.cpp:16: within this context
make: *** [syntax.o] Error 1


Here's the constructor:

HSyntax::HSyntax()
:QSyntaxHighlighter(edit)
{}


This is supposed to install the syntax highlighter into QTextEdit *edit.

The relevant parts of the main window class (derived from QMainWindow)

Q_OBJECT
public:
HMainWindow();
~HMainWindow();
QTextEdit *edit;


The relevant part of the main window implementation:

edit = new QTextEdit(this, "Editor");


When I was trying to debug it, I tried using QTextEdit *edit =..., but that didn't help.

I subclassed QSyntaxHighlighter, but it doesn't have a Q_OBJECT macro in it, since it doesn't need one. No new signals or slots.

ariell
02-09-2003, 08:39 PM
I subclassed QSyntaxHighlighter, but it doesn't have a Q_OBJECT macro in it, since it doesn't need one. No new signals or slots.
...
Use Q_OBJECT. There's a good chance, signals and slots inside your BASE-CLASS don't work. It actually depends on lots of circumstances, but as a rule of thumb: in qt use this macro (finally ev'rything IS derived from QObject).
Anyway, it's late at night here in Europe. I gonna review your code t'row and get you an answer.
Best,
ariell.

Dun'kalis
02-11-2003, 11:27 PM
Tried the Q_OBJECT, and it gives me the EXACT same error.

As an aside, is it always a good idea to use Q_OBJECT, even when the class has no signals/slots?

bwkaz
02-11-2003, 11:46 PM
Post, from /opt/qt/include/qsyntaxhighlighter.h, lines 65-75 or so. Also, lines 10-20 or so from syntax.cpp would be helpful.

It might be that the QSyntaxHighlighter class defines its own "edit" variable that you can't change, and for SOME strange reason, the compiler is seeing that one first. Maybe if you change the variable name?

ariell
02-12-2003, 08:22 AM
Hi there again,

I downloaded Qt 3/X11 to review that problem.

I think the solution is quite simple.
As I understand, "your base class" QSyntaxhighlighter (QSHL) has a private data-member QTextEdit* edit.
QSHL's constructor takes an argument to know where the class is "installed on", namely an instance of QTextEdit. Ownership of class is being transferred to QTextEdit as soon as QSHL is constructed.
Thus: If you declare an instance of QTextEdit within your main window you can't call it edit, for there is no way for a compiler to "recognize" WHICH edit you're currently referring to.
Consider this: edit (declared in main window) can not be passed to QSHL as long as QSHL already HAS (a private data member) called edit, too.

Hope that sounds plausible. Look up header files, qsyntaxhighlighter.h in particular.

As for Q_OBJECT,as a thumb of rule: use it. Q_OBJECTS prupose is (indeed) to provide signals/slots. You don't need signals/slots- you don't need Q_OBJECT. But what if you gonna derive one more class that you want to make use of signals/slots?
That moc generated code is pretty fast, there's almost no "overhead" at all.

Hope that helped,
best,
ariell.

Dun'kalis
02-12-2003, 05:07 PM
Wow, thanks. I changed every instance of edit to editor, and it doesn't give me that error anymore.

However, I get the following:

syntax.cpp: In constructor `HSyntax::HSyntax()':
syntax.cpp:16: `editor' undeclared (first use this function)
syntax.cpp:16: (Each undeclared identifier is reported only once for each
function it appears in.)

The other parts compile properly.

This is the first complex application I've ever tried to write in Qt, so please forgive my ignorance. I'm still learning it...

If I add a declaration for QTextEdit in the public of the syntax, it compiles, but (for obvious reasons) it doesn't highlight syntax.

ariell
02-12-2003, 05:54 PM
you're very welcome,
that's what we do in the unix-world: help each other...

As for the most recent error, I need to know more code.

Best,
ariell.