Show / Hide large number of QGraphicsItems with toggle switch or something else
-
Hi,
as described here I develop an application that should display a large number of
QGraphicLineItems
in a scene. The lines are ordered in categories. For example category A has 5 lines and category B has 50 lines and so on.I want to use a
QComboBox
to show the lines in the scene. If a category is selected the data is displayed, but the removal of the lines did not work. Many lines in the category are at the same postion. So the lines of category B overlays the lines of category A.After few tests I get no idea how to realize that. I wrote the following code to add the lines and it works but at the moment I think this is a trap, because it seams to me that this solution makes the removal impossible.
//first store the lines and the description of the lines into a QList void View::addLinesToList(QString name, int line) { LineData lineData; lineData.name = name; lineData.line = line; m_lineData.push_back(lineData); } //create a new LineItem with necessary data that descripes the line void View::createLineItems(QString name, QString nameStruct, QColor color, int line) { LineItem *lineItem = new LineItem(name, nameStruct, color, line); if (name == nameStruct) { m_scene->addItem(lineItem); } } /* * read the data from the QList, paste the values to the function. * the function is connected to a combobox and is called whenever the user clicks a combobox item. */ void View::paintLines(int index) { for (int i = 0; i <= m_lineData.count(); ++i) { switch (index) { case 0: createLineItems(m_lineData.at(i).name, ancName.extendedAudioCtrlPacketGroup8, ancColor.audioColorGroup1, m_lineData.at(i).line); break; case 1: createLineItems(m_lineData.at(i).name, ancName.extendedAudioCtrlPacketGroup7, ancColor.audioColorGroup1, m_lineData.at(i).line); break; //case 2, case 3, case 4... } } }
I thought that this is a simple task and normally adding and removing / set visability should be simple with a single item.
Also at the moment i 'am not sure if I have to work with the scene to remove the data or with the LineItem.Do this code makes sense?
Kind regards
-
Hi,
as described here I develop an application that should display a large number of
QGraphicLineItems
in a scene. The lines are ordered in categories. For example category A has 5 lines and category B has 50 lines and so on.I want to use a
QComboBox
to show the lines in the scene. If a category is selected the data is displayed, but the removal of the lines did not work. Many lines in the category are at the same postion. So the lines of category B overlays the lines of category A.After few tests I get no idea how to realize that. I wrote the following code to add the lines and it works but at the moment I think this is a trap, because it seams to me that this solution makes the removal impossible.
//first store the lines and the description of the lines into a QList void View::addLinesToList(QString name, int line) { LineData lineData; lineData.name = name; lineData.line = line; m_lineData.push_back(lineData); } //create a new LineItem with necessary data that descripes the line void View::createLineItems(QString name, QString nameStruct, QColor color, int line) { LineItem *lineItem = new LineItem(name, nameStruct, color, line); if (name == nameStruct) { m_scene->addItem(lineItem); } } /* * read the data from the QList, paste the values to the function. * the function is connected to a combobox and is called whenever the user clicks a combobox item. */ void View::paintLines(int index) { for (int i = 0; i <= m_lineData.count(); ++i) { switch (index) { case 0: createLineItems(m_lineData.at(i).name, ancName.extendedAudioCtrlPacketGroup8, ancColor.audioColorGroup1, m_lineData.at(i).line); break; case 1: createLineItems(m_lineData.at(i).name, ancName.extendedAudioCtrlPacketGroup7, ancColor.audioColorGroup1, m_lineData.at(i).line); break; //case 2, case 3, case 4... } } }
I thought that this is a simple task and normally adding and removing / set visability should be simple with a single item.
Also at the moment i 'am not sure if I have to work with the scene to remove the data or with the LineItem.Do this code makes sense?
Kind regards
@makopo You can use https://doc.qt.io/qt-6/qgraphicsscene.html#removeItem to remove items from the scene. Don't forget to also delete the items by yourself after removing from the scene if you do not need them anymore.
-
Hi,
as described here I develop an application that should display a large number of
QGraphicLineItems
in a scene. The lines are ordered in categories. For example category A has 5 lines and category B has 50 lines and so on.I want to use a
QComboBox
to show the lines in the scene. If a category is selected the data is displayed, but the removal of the lines did not work. Many lines in the category are at the same postion. So the lines of category B overlays the lines of category A.After few tests I get no idea how to realize that. I wrote the following code to add the lines and it works but at the moment I think this is a trap, because it seams to me that this solution makes the removal impossible.
//first store the lines and the description of the lines into a QList void View::addLinesToList(QString name, int line) { LineData lineData; lineData.name = name; lineData.line = line; m_lineData.push_back(lineData); } //create a new LineItem with necessary data that descripes the line void View::createLineItems(QString name, QString nameStruct, QColor color, int line) { LineItem *lineItem = new LineItem(name, nameStruct, color, line); if (name == nameStruct) { m_scene->addItem(lineItem); } } /* * read the data from the QList, paste the values to the function. * the function is connected to a combobox and is called whenever the user clicks a combobox item. */ void View::paintLines(int index) { for (int i = 0; i <= m_lineData.count(); ++i) { switch (index) { case 0: createLineItems(m_lineData.at(i).name, ancName.extendedAudioCtrlPacketGroup8, ancColor.audioColorGroup1, m_lineData.at(i).line); break; case 1: createLineItems(m_lineData.at(i).name, ancName.extendedAudioCtrlPacketGroup7, ancColor.audioColorGroup1, m_lineData.at(i).line); break; //case 2, case 3, case 4... } } }
I thought that this is a simple task and normally adding and removing / set visability should be simple with a single item.
Also at the moment i 'am not sure if I have to work with the scene to remove the data or with the LineItem.Do this code makes sense?
Kind regards
@makopo said in Show / Hide large number of QGraphicsItems with toggle switch or something else:
because it seams to me that this solution makes the removal impossible.
You are indeed making removal difficult for yourself!
Firstly, to remove items from the scene you do indeed do as @jsulm has said,
QGraphicsScene::removeItem()
, and you need todelete
the line because you originallynew
ed it.Your problem, if I understand/guess right from your code, is that you have a
m_lineData
holding a list ofLineData
which only seem to contain aname
and someint
. And I am guessing you later want to remove lines by theirname
? How are you going to know whichQGraphicLineItem
a givenLineData
refers to so as to remove it from the scene? You talk about "Many lines in the category are at the same postion. So the lines of category B overlays the lines of category A.", which might imply you are doing something about locating the line to remove by position, but as you say that does not sound good for identifying the right line. So, how/what do you remove by, how does that relate to bothm_lineData
and the actual line of theQGraphicsScene
? -
@makopo said in Show / Hide large number of QGraphicsItems with toggle switch or something else:
because it seams to me that this solution makes the removal impossible.
You are indeed making removal difficult for yourself!
Firstly, to remove items from the scene you do indeed do as @jsulm has said,
QGraphicsScene::removeItem()
, and you need todelete
the line because you originallynew
ed it.Your problem, if I understand/guess right from your code, is that you have a
m_lineData
holding a list ofLineData
which only seem to contain aname
and someint
. And I am guessing you later want to remove lines by theirname
? How are you going to know whichQGraphicLineItem
a givenLineData
refers to so as to remove it from the scene? You talk about "Many lines in the category are at the same postion. So the lines of category B overlays the lines of category A.", which might imply you are doing something about locating the line to remove by position, but as you say that does not sound good for identifying the right line. So, how/what do you remove by, how does that relate to bothm_lineData
and the actual line of theQGraphicsScene
?@JonB said in Show / Hide large number of QGraphicsItems with toggle switch or something else:
And I am guessing you later want to remove lines by their name? How are you going to know which QGraphicLineItem a given LineData refers to so as to remove it from the scene?
Yes, I want to remove the data by the name. In fact, every name of a category represents a data packet and the lines define where the data packets are located.
Its true that some data packets are located at the same postion. For example "Category A" represents data that is located at line 9 and 571 and "Category B" is located in most of the 50 first lines of a video frame.I have a section in my program that sorts this data. If fetched with an API, every data packet has a ID, but no name. So I use a function that set a relation between the id of the packet and the name. The names comes from a struct, I had defined globally. Then this data is send to slots for further processing. As I can see in a table view this sortation works.
void InputReader::dataNameRelation(QString &did, QString &sdidOrDbn, QVariant &udw, int &line) { ANCDataNames ancName; if (did == "A0") { sendAncillaryData(ancName.extendedAudioCtrlPacketGroup8, did, sdidOrDbn, udw, line); } //.... and so on }
Ideally the lines should be removed if the user clicks an other item in the combo box. Also an button that removes and deletes all lines would be nice. The problem I can not manage is that the instance of
LineItem
is created inside the for loop. So accessing the object from outside is impossible.Because I did not give a information about it: I talk about data packets that are transported in a special data space of a videostream.
-
@JonB said in Show / Hide large number of QGraphicsItems with toggle switch or something else:
And I am guessing you later want to remove lines by their name? How are you going to know which QGraphicLineItem a given LineData refers to so as to remove it from the scene?
Yes, I want to remove the data by the name. In fact, every name of a category represents a data packet and the lines define where the data packets are located.
Its true that some data packets are located at the same postion. For example "Category A" represents data that is located at line 9 and 571 and "Category B" is located in most of the 50 first lines of a video frame.I have a section in my program that sorts this data. If fetched with an API, every data packet has a ID, but no name. So I use a function that set a relation between the id of the packet and the name. The names comes from a struct, I had defined globally. Then this data is send to slots for further processing. As I can see in a table view this sortation works.
void InputReader::dataNameRelation(QString &did, QString &sdidOrDbn, QVariant &udw, int &line) { ANCDataNames ancName; if (did == "A0") { sendAncillaryData(ancName.extendedAudioCtrlPacketGroup8, did, sdidOrDbn, udw, line); } //.... and so on }
Ideally the lines should be removed if the user clicks an other item in the combo box. Also an button that removes and deletes all lines would be nice. The problem I can not manage is that the instance of
LineItem
is created inside the for loop. So accessing the object from outside is impossible.Because I did not give a information about it: I talk about data packets that are transported in a special data space of a videostream.
@makopo
So after all of this explanation it seems you need to be able to map fromLineData
(where name is held) to theQGraphicLineItem
for it so that you can delete it, don't you think?The problem I can not manage is that the instance of LineItem is created inside the for loop. So accessing the object from outside is impossible.
No idea what you mean by this. You need to be able to get from a
LineItem
to theQGraphicsItem
, so implement it, in whatever way. If you can't, then you cannot remove graphics items by their name stored inm_lineData
. -
You could use QGraphicsItemGroup where each of your categories would have its own instance of QGraphicsItemGroup. It inherits
QGraphicsItem
so you can call show()/hide() on the group object to show/hide all items in the group. -
@makopo
So after all of this explanation it seems you need to be able to map fromLineData
(where name is held) to theQGraphicLineItem
for it so that you can delete it, don't you think?The problem I can not manage is that the instance of LineItem is created inside the for loop. So accessing the object from outside is impossible.
No idea what you mean by this. You need to be able to get from a
LineItem
to theQGraphicsItem
, so implement it, in whatever way. If you can't, then you cannot remove graphics items by their name stored inm_lineData
.@JonB said in Show / Hide large number of QGraphicsItems with toggle switch or something else:
So after all of this explanation it seems you need to be able to map from LineData (where name is held) to the QGraphicLineItem for it so that you can delete it, don't you think?
Maybe I'am too much junior to understand what you mean, but do you think I don't do that?
LineItem
is derived fromQGraphicsItem
, but only overridesboundingRect()
andpaint(...)
to draw a line.
View::paintLines(...) starts a loop to read the whole data from a list. This data is copied to createLines which creates an instance ofLineItem
.Have to think about it.
@mchinand also thank you for your hint. I have to take a look.