Getting a string from QGraphicsSimpleTextItem from QGraphicsItem foreach loop? - c++

I am making an image annotation system Using qrect and Simple text items.
I am trying to store the string values from the QGraphicssimpletext items into a JSON file to save and load the annotation boxes. The rectangles work fine but I cannot understand how to get a string value. This is the foreach I am trying to loop through for each item, and as the text items are children of the rectangles the position does not matter.
foreach(QGraphicsItem* item, items())
{
arrayPosX.push_back(item->x());
arrayHeight.push_back(item->boundingRect().height());
arrayWidth.push_back(item->boundingRect().width());
arrayPosY.push_back(item->y());
arrayAnnotation.push_back(item->?);
}
Both the simple text and rect items are added to the scene using
itemToDraw = new QGraphicsRectItem;
this->addItem(itemToDraw);
simpleTextToDraw = new QGraphicsSimpleTextItem;
this->addItem(simpleTextToDraw);
I would simply like to know how I could get the string values from the simple text item as to allow saving and loading of both strings and boxes, not just boxes which the current system can do.

You have to cast and verify that the pointer is not null:
// ...
arrayPosY.push_back(item->y());
if(QGraphicsSimpleTextItem* text_item = qgraphicsitem_cast<QGraphicsSimpleTextItem *>(item)){
arrayAnnotation.push_back(text_item->text());
}

Related

using one Qcombobox to set value to several labels, C++

im trying to set the value from a combobox to multiple Qlabels, the idea is to populate the QcomboBox with all the values, then according to the number, (ejem 15.6) the corresponding label should change the problem is, theres too many of them to simply use a switch of something similar, but all the names of the labels are similar, HumSec_val156 corresponds to 15.6 the main idea was to use
Silo* silo = new Silo;
QString number = widget.QComboBox->currentText();
QString nameOfLabel = "HumSec_val";
nameOfLabel.append(QString::number(number));
silo->findchild<QLabel*>(nameOfLabel)->setText(valuefromCombobox);
but everytime it simply return an empty string, i did try using somthing simplier like
widget.nameOfLabel->setText(valuefromComboBox);
but nameOfLabel its just a qstring so i can mix it with the code generated from designer. Any idea what can i do? do i need to create something like a scoped enum or similar?
below i add a picture of what im doing
If I would do something like this, I would probably create a QHash<QString, QLabel*> and use that as a cache to find the matching QLabel for each name.
Declaration:
QHash<QString, QLabel*> m_hash
Storing value:
m_hash[labelName] = labelPtr;
Reading value:
QLabel* labelPtr = m_hash.value(labelName, nullptr);
if (labelPtr)
{
// Access label
}
When you remove a label remember to remove it from the hash as well:
const QString key = m_hash.key(labelPtr);
m_hash.remove(key);

How can I set the color of a specific line in a libgdx list?

I am developing a list and I want to highlight certain lines by showing the font color in red. Is this possible?
EDIT:
Ok, here a simplified version of my code:
Skin defListSkin = new Skin(Gdx.files.internal("data/uiskin.json"));
List listHistory = new List<String>(defSkin);
// Here I set the general font color for the list
List.ListStyle listStyle = listHistory.getStyle();
listStyle.font = fontList;
listStyle.fontColorUnselected = Color.LIGHT_GRAY;
listHistory.setStyle(listStyle);
String[] items = new String[20];
// Example of item[]
// item[0]: "John 12"
// item[1]: "Amy -3" <-- I want certain lines to appear in red (e.g. those with negative numbers)
// Populate the list
listHistory.setItems(items);
// Drawing the list (actual draw happens in render() of course)
Table myTable = new Table();
myTable.add(listHistory);
stage.addActor(myTable);
Use the Color Markup Language that Libgdx supports.
The markup syntax is really simple but still versatile:
[name] Sets the color by name. There are a few predefined colors, see the Colors.reset() method for an exhaustive list. Users can define their own colors through the methods of the Colors class.
[#xxxxxxxx] Sets the color specified by the hex value xxxxxxxx in the form RRGGBBAA where AA is optional and defaults to 0xFF.
[] Sets the color to the previous color (kind of optional end tag)
[[ Escapes the left bracket.
Markup is disabled by default. Use the public member font.getData().markupEnabled to turn it on/off.
Reference: https://github.com/libgdx/libgdx/wiki/Color-Markup-Language
If you want a more complex html like markup you can use those templates: https://github.com/czyzby/gdx-lml, live tests: http://czyzby.github.io/gdx-lml-tests/
I know what you mean, and I don't think it is possible. The list items are all linked to the same listStyle, and the only way to change the color of the list items is to make a new style for listHistory and change the font color of this style, however if you do this, it changes every item in the list to that new font color. My suggestion would be to create two separate lists and two separate ListStyles and the lines you want red be in one list and have one style and the lines you don't want to be red be in another list and have a different style. Hope this helps

Get data from selected row of gtk treeview - gtkmm, c++

I have a GTK application that has a window with a treeview and a button. When the button is clicked I need to get the data from the first (and only) column of the selected row in the treeview.
This is the class for the columns:
class ModelColumns:
public Gtk::TreeModel::ColumnRecord{
public:
ModelColumns(){ add(m_port_name); }
Gtk::TreeModelColumn<Glib::ustring> m_port_name;
};
This is like in the example here but with only one column: http://www.lugod.org/presentations/gtkmm/treeview.html
This is the button click signal handler at the moment:
tvPorts is the treeview widget
tvPortsList is the listStore for the treeview
static
void on_btnPortSelectOK_clicked (){
Glib::RefPtr<Gtk::TreeSelection> selection = tvPorts->get_selection();
Gtk::TreeModel::iterator selectedRow = selection->get_selected();
//Now what?
//Need to get data from selected row to display it.
}
I have searched the documentation and many examples to try and find out what to do next but can't find any examples for gtkmm, I can only find examples for c or python implementations.
As far as I can tell, I need to get a TreeRow object from my iterator (selectedRow) how do I do this?
Thanks.
Update:
I am now using this code and it almost works.
The only problem is that it prints the previous selection.
The first time I select something and then press the button it prints only a new line. The second time it prints what was selected the first time, the third prints the second, etc.
Glib::RefPtr<Gtk::TreeSelection> selection = tvPorts->get_selection();
Gtk::TreeModel::iterator selectedRow = selection->get_selected();
Gtk::TreeModel::Row row = *selectedRow;
Glib::ustring port = row.get_value(m_Columns.m_port_name);
printf("\nselected port: %s", port.data());
This seems odd.
(m_Columns is an instance of the ModelColumns class)
Update 2:
Fixed the problem by adding fflush(stdout);
It all works now, thanks.
The docs say to simply dereference the iter to get the TreeRow:
Gtk::TreeModel::Row row = *iter; // 'iter' being your 'selectedRow'
std::cout<<row[0];

QTableView with multiline cell

How can I create a QTableView multiline cell?
I'm filling the table using the code bellow.
But Whem GetDescription() returns a long string, the content is terminated with ...
There is some way to automatic break the line?
QStandardItemModel * model = new QStandardItemModel(logos.size(), 2, this);
model->setHorizontalHeaderItem(0, new QStandardItem(QString("")));
model->setHorizontalHeaderItem(1, new QStandardItem(QString("Nome")));
model->setHorizontalHeaderItem(2, new QStandardItem(QString("Descrição")));
int row = 0;
foreach(Item * item, items)
{
QStandardItem* check = new QStandardItem(true);
check->setCheckable(true);
model->setItem(row, 0, check);
QStandardItem *nameItem = new QStandardItem(QString(item->GetName()));
nameItem->setEditable(false);
model->setItem(row, 1, nameItem);
QStandardItem *descriptionItem = new QStandardItem(item->GetDescription());
descriptionItem->setEditable(false);
descriptionItem->setToolTip(logo->GetDescription());
model->setItem(row, 2, descriptionItem);
row++;
}
ui->tableView->setModel(model);
ui->tableView->resizeColumnToContents(0);
ui->tableView->resizeColumnToContents(1);
ui->tableView->horizontalHeader()->setSectionResizeMode(0, QHeaderView::Fixed);
ui->tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Fixed);
ui->tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
I think word wrapping is what you're looking for. Make sure that you've enabled wordwrap for the QTableView, then manually resize the rows to fit their contents. That will replace the ellipse with the text.
As you mentioned in your answer, you can set the QHeaderView to resize to contents automatically, but if you do a lot of adding and removing this will slow things down. I prefer to manually resize with a large addition/subtraction, particularly since the user might find it annoying to be unable to resize it themselves.
Here's some example code that enables word wrap, sets the ellipse to appear in the middle (my preference), and then manually resizes the row height to fit the contents at word boundaries:
ui->tableView->setWordWrap(true);
ui->tableView->setTextElideMode(Qt::ElideMiddle);
ui->tableView->resizeRowsToContents();
I only add to my code:
ui->tableView->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
As far as I know, the only way to implement multiline text drawing in cells is implementing own delegate.
You can derive from QItemDelegate.
You'll have to
implement own sizeHint function, based on QFontMetrics
and override drawDisplay function to actually display text. You can use QPainter::drawText to display multiline text. So, you don't have to care about drawing focus and selection rectangles and own painting function will be simple.
tableView->resizeRowsToContents();

AS3: Getting the x & y value of a matched string in a text field

I have a text field within Flash that contains a block of (obviously) text.
What I want to do is perform a search on the content of the text field that returns the x & y coordiante and the width & height of the found text. The result will be used to place a visual element over that portion of the text box.
For example:
var pattern:RegExp = /\d+/g;
var found:Array = box.text.match(pattern);
var i:String;
for each(i in found)
{
/**
* Find the x, y, width, height of the matched text in the text field
* Use result to place transparent yellow box around text
*/
}
Which visually should result in something like:
You would want to make use of the TextField class's getCharBoundaries method, which accepts character indexes and returns a Rectangle object.
As far as I know, your match method returns the strings themselves, so first you'll probably need to use the String class's indexOf method, find all your character indexes, pass them to the getCharBoundaries method, then draw some rectangles based on that output.
Here's some reference.
Good luck!