PDA

View Full Version : Painting lines



therealjag
21st March 2006, 15:45
hey there i am trying to create links between nodes that i have made but theres 1 problem. everytime i paint a link the last link that i painted onto the qpainter goes away. how can i keep the links that have been painted before on the link? i store the node Id's in an array and their position with a struct. so i just get a user input as to where they want the link to be created. my code for the painting is shown below:



if( drawLine == 1)
{
painter.setPen(myTextColor());
painter.drawLine( list.position[n1]+offset, list.position[n2]+offset );
painter.drawText(QRect(midpoint,textbox),0,tr("%1").arg(topology[n1][n2]));

}


i also have a capacity number that i wish to appear between the links when they get painted.

jacek
21st March 2006, 16:00
Where do you draw those lines? In paintEvent()?

therealjag
21st March 2006, 16:16
yeah in Paintevent. actaully it doesnt really matter where they get painted as long as they do!

jacek
21st March 2006, 16:22
How many lines do you paint in single call to paintEvent()?

therealjag
21st March 2006, 16:26
just the lines that have been created so far. so for example the nodes are created first and then the user presses a button to create the link. the link then gets created between the nodes that the user specifies and then the user can then go on to create the next link. i just want the links created so far to be printed...

jacek
21st March 2006, 16:34
Could you show more code from your paintEvent()?

therealjag
21st March 2006, 16:48
ok sure here is the code from the QPaintEvent and below it is the function that gets the user input:



void SortingBox::paintEvent(QPaintEvent * /* event */)
{
QPainter painter(this);
QPoint offset(7,13);
int looplength=0;
foreach (ShapeItem shapeItem, shapeItems)
{

QPoint mid(-shapeItem.position());
//QPoint offset(7,13);
QPoint text(100,100);

painter.translate(shapeItem.position());
painter.setBrush(shapeItem.color());
painter.drawPath(shapeItem.path());
painter.translate(-shapeItem.position());
painter.setPen(initialItemColor());
painter.drawText((shapeItem.position() + offset),tr("%1").arg(shapeItem.instanceNumber()));


list.position[shapeItem.instanceNumber()] = shapeItem.position();
list.nodeID[shapeItem.instanceNumber()] = shapeItem.instanceNumber();
looplength = shapeItem.instanceNumber();
}

QPoint midpoint;
midpoint = ((list.position[n1] + list.position[n2])/2);
QPoint test(100,100);
QSize textbox(100,100);



if( drawLine == 1)
{
painter.setPen(myTextColor());
for(int j=0;j<looplength;j++)
/*{
if(list.nodeID[j]>0 && list.nodeID[j]<100)
{
painter.drawLine( list.position[list.nodeID[j]]+offset, list.position[list.nodeID[j+1]]+offset );
}


}*/

painter.drawLine( list.position[n1]+offset, list.position[n2]+offset );
painter.drawText(QRect(midpoint,textbox),0,tr("%1").arg(topology[n1][n2]));

}
}


function user input( )



void SortingBox::user_input()
{
drawLine = 1;


QLabel *integerLabel = new QLabel(this);
bool ok;
n1 = QInputDialog::getInteger(this, tr("QInputDialog::getInteger()"),
tr("enter first node to link:"), 25, 0, 100, 1, &ok);

if(ok)
integerLabel->setText(tr("%1").arg(n1));

n2 = QInputDialog::getInteger(this, tr("QInputDialog::getInteger()"),
tr("enter second node to link:"), 25, 0, 100, 1, &ok);

if(ok)
integerLabel->setText(tr("%1").arg(n2));

topology[n1][n2] = QInputDialog::getInteger(this, tr("QInputDialog::getInteger()"),
tr("required capacity:"), 25, 0, 100, 1, &ok);

if(ok)
integerLabel->setText(tr("%1").arg(topology[n1][n2]));

}

jacek
21st March 2006, 17:05
foreach (ShapeItem shapeItem, shapeItems)
{
//...
}
What are these ShapeItems?



for(int j=0;j<looplength;j++)
/*{
if(list.nodeID[j]>0 && list.nodeID[j]<100)
{
painter.drawLine( list.position[list.nodeID[j]]+offset, list.position[list.nodeID[j+1]]+offset );
}


}*/

painter.drawLine( list.position[n1]+offset, list.position[n2]+offset );
painter.drawText(QRect(midpoint,textbox),0,tr("%1").arg(topology[n1][n2]));

}
Where do you change n1 and n2?

Your paintEvent() should be something like this:
for each edge in Edges:
draw line from edge.startNode.point to edge.endNode.point
draw text edge.label at midPoint( edge.startNode.point, edge.endNode.point )

therealjag
21st March 2006, 17:12
Quote:
Qt Code:
foreach (ShapeItem shapeItem, shapeItems) { //...}

What are these ShapeItems?


the shapeItems are just my nodes that i have created. they arent linked in any programmable way like in a linked list or anything they have just been created individually.
n1 and n2 get changed when the user enters their value so the first user input gets set to n1 and the second user input gets set to n2. the capacity for the link then gets asked for after that.

jacek
21st March 2006, 17:17
n1 and n2 get changed when the user enters their value so the first user input gets set to n1 and the second user input gets set to n2. the capacity for the link then gets asked for after that.
So in fact your paintEvent() draws only one edge?

therealjag
21st March 2006, 21:02
yeah it only draws 1 edge at a time but is there a way to keep the older ones drawn on the screen?

jacek
21st March 2006, 21:06
yeah it only draws 1 edge at a time but is there a way to keep the older ones drawn on the screen?
You can't, you must draw all of them every time paintEvent() is invoked. The only thing you could do is to paint them on a pixmap and then paint that pixmap in paintEvent().

therealjag
21st March 2006, 21:43
how would i generate a pixmap for my code?

jacek
21st March 2006, 21:56
Just create it and paint on it using QPainter, but IMO it would be easier just to paint all edges every time (unless you have a really big graph). You can try Qanava (http://www.qtcentre.org/index.php?option=com_weblinks&task=view&catid=23&id=23)

therealjag
21st March 2006, 21:59
i looked at Qavana but it seems to be unavailable for windows. i guess theres no other way of doing it is there?

therealjag
21st March 2006, 22:03
how would i paint all edges everytime? would i haveto ask the user for all inputs each time?

jacek
21st March 2006, 22:03
i looked at Qavana but it seems to be unavailable for windows.
Then why all screenshots were taken on windows? ;)


i guess theres no other way of doing it is there?
If you can draw one line, then just add a loop and you're done.

jacek
21st March 2006, 22:04
how would i paint all edges everytime? would i haveto ask the user for all inputs each time?
No, just ask once and save the data in proper data structure.

therealjag
21st March 2006, 22:22
ru talking about an array or an array of structs of some sort? i was thinking about using linked lists but im not very sure about using them in qt...

jacek
21st March 2006, 22:33
ru talking about an array or an array of structs of some sort? i was thinking about using linked lists but im not very sure about using them in qt...
There are many options. You can keep a list of nodes and each node can contain a list of edges. You can also keep a list of nodes and a list of edges.

First think what data you need to store and how would you like to access it, then choose a data structure that fits the best.

therealjag
21st March 2006, 23:15
how do i construct a list og edges then..i looked at the linked list library but then i got confused with qvector aswell..which one do i use?

jacek
22nd March 2006, 00:01
how do i construct a list og edges then..i looked at the linked list library but then i got confused with qvector aswell..which one do i use?
It depends. You can add items to the list faster, but accessing elements randomly is much slower than in vector. If you plan to add a lot of items and you will only read the whole list at once, you should use linked list. If you will access single items, you should use a vector. There is also a QList which is something between linked list and a vector.

therealjag
22nd March 2006, 15:29
hey again i was thinking of using an array of structs where my struct would be:

struct Link{

int n1;
int n2;
int capacity
}

how would i create an array of this??

jacek
22nd March 2006, 15:41
QVector<Link> links;

ePharaoh
22nd March 2006, 15:45
no offense, but you really ought to learn some basics of data structures. there's no point in learning qt data-structures without knowing basic DS theory.

it is a bit like learning to use the harpoon, without knowing what a whale is ;)

grab a text book on data-structures; trust me, it will go a long way to ease programming.

therealjag
22nd March 2006, 22:11
no offense, but you really ought to learn some basics of data structures. there's no point in learning qt data-structures without knowing basic DS theory.

it is a bit like learning to use the harpoon, without knowing what a whale is


yeah you're probably right but its a project im doing and i dont have much time to do it which is why i havent gone about it the proper way. i guess in the summer i could read to my hearts content and not bother you guys all the time :o

therealjag
23rd March 2006, 02:05
hey there i tried using the QVector to make my struct into an array but the program crashes when i try to run it. it compiles ok but there seems to be a problem with the way i am referencing the QVector...heres my code below:



links[0].n2 = QInputDialog::getInteger(this, tr("QInputDialog::getInteger()"),
tr("enter second node to link:"), 25, 0, 100, 1, &ok);

if(ok)
integerLabel->setText(tr("%1").arg(links[0].n2));


any help would be much appreciated again

jpn
23rd March 2006, 06:22
void QVector::append ( const T & value ) (http://doc.trolltech.com/4.1/qvector.html#append)
Inserts value at the end of the vector.

therealjag
23rd March 2006, 18:19
hey there i tried .append() but it still didnt work. i get an error saying:



"not enough contextual info to determine type"


i tried it with the following piece of code:



links.capacity.append(topology[n1][n2]);


what am i doing wrong?

jacek
23rd March 2006, 18:22
links.capacity.append(topology[n1][n2]);
What types do the links and links.capacity have?

therealjag
23rd March 2006, 18:31
links is just my struct Link and it contains the integer which is called capacity..
my struct is shown below:



struct Link{

int n1;
int n2;
int capacity;
}

the 2-d array is just an integer as well

jacek
23rd March 2006, 18:54
int doesn't have an append() method. You probably wanted to invoke that method on some other object.

therealjag
23rd March 2006, 19:03
int doesn't have an append() method.


ok, so how do i add that number from topology[n1][n2] to link.capacity? i also tried insert() with my code instead of append and it still didnt work??

jacek
23rd March 2006, 21:05
ok, so how do i add that number from topology[n1][n2] to link.capacity? i also tried insert() with my code instead of append and it still didnt work??
What do you mean by "add"? capacity in an integer and it can hold only one value. You should create a list or vector and add values to it.

therealjag
23rd March 2006, 22:43
What do you mean by "add"? capacity in an integer and it can hold only one value. You should create a list or vector and add values to it.


oh sorry i was a bit unclear i just want the value at capacity[n1][n2] to be equal to one of the instances in my vector 'links' and i want it to be stored into link.capacity?