QmodelIndex and header data - c++

I have a 4 tableviews in my ui screen .In my header data function for 4 views , I just need one 1 row name- temperature for view 1 and 3 and four rows with name field 1x,field 4x, field 10x, field 40x respectively.
My function is
virtual QVariant headerData(int section,Qt::Orientation orientation,
int role = Qt::DisplayRole) const
{
switch(role)
{
case Qt::DisplayRole:
switch (orientation)
{
case Qt::Vertical:
switch (m_channel)
{
case 0:
switch (section) // Range
{
case 0:
return "Temperature1";
}
case 1:
switch (section) // Range
{
case 0:
return "Field 1x range";
case 1:
return "Field 4x range";
case 2:
return "Field 10x range";
case 3:
return "Field 40x range";
}
case 2:
switch (section) // Range
{
case 0:
return "Temperature2";
}
case 3:
switch (section) // Range
{
case 0:
return "Field 1x range";
case 1:
return "Field 4x range";
case 2:
return "Field 10x range";
case 3:
return "Field 40x range";
}
But, the screen when compiled shows temperature,field 4x, field 10x, field 40x for views 1 and view 3, which I don't wont
Please help

You are missing breaks in your switch statement. For example:
switch (m_channel)
{
case 0:
switch (section) // Range
{
case 0:
return "Temperature1";
}
break; // <-- You need this.
case 1:
...
It's also generally a good idea to provide a default label for switch statements.

Related

how to only indent brackets after case labels using clang-format

I wanna a style that only indent brackets after case labels, while keeping case label not indented.
this is what I want:
switch(a)
{
case 1:
{
do_some_thing();
}
break;
}
I find an option IndentCaseLabels, but it will the whole things include the case label, neither true or false isn't what I want
true:
switch(a)
{
case 1:
{
do_some_thing();
}
break;
}
false:
switch(a)
{
case 1:
{
do_some_thing();
}
break;
}
Is this style possible in clang-format? If is, how could I Configure it?
It's just immediate above one you found in the manual.
IndentCaseBlocks: true
Indent case label blocks one level from the case label.
false: true:
switch (fool) { vs. switch (fool) {
case 1: { case 1:
bar(); {
} break; bar();
default: { }
plop(); break;
} default:
} {
plop();
}

How to return QVariant type array

I am recently creating a model for qml with c++, but I face a problem when returning a QVariant type empty array. How should I define my return statement?
switch (role) {
case NameRole:
return QVariant(QStringLiteral("AAAAA"));
case LevelRole:
return QVariant(QStringLiteral("1"));
case ParentRole:
return QVariant(QStringLiteral("null"));
case SublevelRole:
return ???// I would like to return an empty array
}
Use QVariantList:
switch (role) {
case NameRole:
return QVariant(QStringLiteral("AAAAA"));
case LevelRole:
return QVariant(QStringLiteral("1"));
case ParentRole:
return QVariant(QStringLiteral("null"));
case SublevelRole:
return QVariantList();
}

Printing out selected items from an enum flag

I have the following enum (which later will grow larger!):
enum TrainingFilters {
NONE = 0,
GAUSS = 1,
SOBEL = 2,
FEATURE = 4
};
I have to print out string representation of the all possible combination. For now, a not-leangthy switch statement works fine, but if I add more items it will be disaster!
void Manager::setFilters(int filters)
{
QString what("Selected filters:");
switch (filters) {
case 0:
what.append(" NONE ");
break;
case 1:
what.append(" GAUSS ");
break;
case 1 | 2:
what.append(" GAUSS SOBEL ");
break;
case 2:
what.append(" SOBEL ");
break;
case 2 | 4:
what.append(" SOBEL FEATURE ");
break;
case 4:
what.append(" FEATURE ");
break;
case 1 | 4:
what.append(" GAUSS FEATURE ");
break;
case 1 | 2 | 4:
what.append(" GAUSS SOBEL FEATURE ");
break;
default:
qDebug() << "Invalid FILTERS enum received!";
return;
}
qDebug() << what;
mFilters = static_cast<TrainingFilters>(filters);
}
P.S: I have a few checkbox items in the user interface, and I should do some stuff according to the checked checkboxes. I use it like this:
var a, b,c;
cbGauss.checked ? a = 1 : a = 0;
cbSobel.checked ? b = 2 : b = 0;
cbFeat.checked ? c = 4 : c = 0;
cpManager.setFilters(a | b | c);
So my qustion is what is the best/easiest/smartest way to achieve this?
You could simply do
if (filters & 1)
what.append("GAUSS ");
if (filters & 2)
what.append("SOBEL ");
if (filters & 4)
what.append("FILTER ");
And so on. This way you can easily add new ones. Of course you have to check for zero and then add NONE.

Switch statement doesn't work with enum (C++)

enum Maximum_Value{
MAXIMUM_VALUE_1 = 0,
MAXIMUM_VALUE_7 = 1,
MAXIMUM_VALUE_15 = 2,
MAXIMUM_VALUE_26 = 3,
MAXIMUM_VALUE_34 = 4
};
int value_from_function = functionetc();
switch(value_from_function){
MAXIMUM_VALUE_1: printf("MAXIMUM_VALUE_1 :%x\n",value_from_function); break;
MAXIMUM_VALUE_7: printf("MAXIMUM_VALUE_7 :%x\n",value_from_function); break;
MAXIMUM_VALUE_15: printf("MAXIMUM_VALUE_15 %x\n",value_from_function); break;
MAXIMUM_VALUE_26: printf("MAXIMUM_VALUE_26 %x\n",value_from_function); break;
MAXIMUM_VALUE_34: printf("MAXIMUM_VALUE_34 %x\n",value_from_function); break;
default: printf("default :%x\n",value_from_function);
}
The code above always seems to hit the default statement, printing "default :0" even though that should hit MAXIMUM_VALUE_1.
I've tried casting the variable in switch to no effect
I guess I should save the return value into a variable of type "Maximum_Value", but why doesn't the code work anyway?
Edit: Thanks for pointing out the awfully stupid mistake everyone :P. The root of the problem was copying coding from systemverilog, which uses 'case' as a keyword instead of 'switch', and doesn't require 'case' at the start of each case
Enumerators aren't labels but switch statements jump to labels. You use case to create a label switch statements can jump to:
case MAXIMUM_VALUE_1: ...; break;
Add case keyword then it will work.
case MAXIMUM_VALUE_1: printf("MAXIMUM_VALUE_1 :%x\n",value_from_function); break;
case MAXIMUM_VALUE_7: printf("MAXIMUM_VALUE_7 :%x\n",value_from_function); break;
case MAXIMUM_VALUE_15: printf("MAXIMUM_VALUE_15 %x\n",value_from_function); break;
case MAXIMUM_VALUE_26: printf("MAXIMUM_VALUE_26 %x\n",value_from_function); break;
case MAXIMUM_VALUE_34: printf("MAXIMUM_VALUE_34 %x\n",value_from_function); break;
default: printf("default :%x\n",value_from_function);
you are missing the case keyword before every label!
syntax of switch case is-
switch(type){
case type1: ....; break;
case type2: ....; break;
......
default: .....;
}

Simplyfing long code lines

This code is to list a cards deck in string (Kh,6c,5h, etc..) from a int (0 from 51) or vice versa.
I have written code for it but it seems very long. Is there a more efficient way to write this ?
I want to do this both way too, send a string to a function and get an int.
std::string Card::getString(int card) {
std::string cardstring;
switch (card) {
case 0:
return "2c";
case 1:
return "3c";
case 2:
return "4c";
case 3:
return "5c";
case 4:
return "6c";
case 5:
return "7c";
case 6:
return "8c";
case 7:
return "9c";
case 8:
return "Tc";
case 9:
return "Jc";
case 10:
return "Qc";
case 11:
return "Kc";
case 12:
return "Ac";
case 13:
return "2d";
case 14:
return "3d";
case 15:
return "4d";
case 16:
return "5d";
case 17:
return "6d";
case 18:
return "7d";
case 19:
return "8d";
case 20:
return "9d";
case 21:
return "Td";
case 22:
return "Jd";
case 23:
return "Qd";
case 24:
return "Kd";
case 25:
return "Ad";
case 26:
return "2h";
case 27:
return "3h";
case 28:
return "4h";
case 29:
return "5h";
case 30:
return "6h";
case 31:
return "7h";
case 32:
return "8h";
case 33:
return "9h";
case 34:
return "Th";
case 35:
return "Jh";
case 36:
return "Qh";
case 37:
return "Kh";
case 38:
return "Ah";
case 39:
return "2s";
case 40:
return "3s";
case 41:
return "4s";
case 42:
return "5s";
case 43:
return "6s";
case 44:
return "7s";
case 45:
return "8s";
case 46:
return "9s";
case 47:
return "Ts";
case 48:
return "Js";
case 49:
return "Qs";
case 50:
return "Ks";
case 51:
return "As";
}
return cardstring;}
thanks
std::string get_card_string(int card)
{
if (card >= 0 && card < 52)
{
std::string s(2,' ');
s[0] = "23456789TJQKA"[card % 13];
s[1] = "cdhs"[card / 13];
return s;
}
return "";
}
The reverse process is a little more complicated. If I thought about it for a while, I might come up with a more clever method, but the obvious choice would be something like this:
std::unordered_map<std::string, int> initialize_card_map()
{
std::unordered_map<std::string, int> m;
for (int i=0; i<52; ++i)
m[get_card_string(i)] = i;
return m;
}
int get_card_number(std::string const & card_string)
{
static std::unordered_map<std::string, int> const m = initialize_card_map();
auto it = m.find(card_string);
if (it != m.end())
return it->second;
return ??? value not found
}
Use an std::array or an std::vector:
std::vector<std::string> cards{
"2c", // index 0
"3c", // index 1
"4c"...
};
std::string Card::getString(int card) { return cards[card]; }
assert(getString(0) == "2c");
Benjamin Lindley`s above answer is great, but if you are writing code like the original post in the first place you need to be asking youself more questions about your design choices:
Why do you have to access the card value via an int?
How about a tuple to represent card values?
Peter Norvig's "Design of Computer Programs" course on Udacity.com's first lesson/lecture seems like it would extremely relevant to you. I suggest taking a look at it.