removeChildByTag: child not found - cocos2d-iphone

Some breakpoints have pointed to the fact that this following line of code sends a CCLog that says removeChildByTag: child not found:
CCMenu* menu = [CCMenu menuWithItems:item1, item3, nil];
The actual creation of item1 and item3 do not cause any unusual CCLOGs but the creation of the menu itself does. Any idea why?

The only place where CCMenu or CCMenuItem send a removeChildByTag message is in the CCMenuItem method -(void)setSelectedIndex:(NSUInteger)index which in turn is called by the initWithTarget and activate methods.
I suppose as long as your menu is working this is nothing to worry about.

Related

How to Change the IconSize for Actions in QMenu?

I am trying to resize the Icons of QActions in the QMenu with the following code but it doesn't work.
QMenu *menu;
menu =new QMenu();
menu->setStyleSheet("QMenu::icon{height:20px;width:20px});"
I would really appreciate it if someone could provide a solution.
Here is the solution that worked for me:
QMenu *menu;
menu =new QMenu();
QToolButton *button=new QToolButton(menu);
button->setFixedSize(50,50);
QWidgetAction *action=new QWidgetAction(this);
action->setDefaultWidget(button);
menu->addAction(action);
We can set style sheet to manage icon size like this:
QAction *action = new QAction("Exit", this);
action->setIcon(QIcon(":/images/resources/exit.png"));
QMenu *menu = new QMenu("File");
menu->addAction(action);
menu->setStyleSheet("QMenu {icon-size: 200px;} QMenu::item {background: transparent;}");
ui->menubar->addMenu(menu);
But it will display in an Improper size, so it's better to use QToolBar.
In your cpp file type this:
ui->ToolBarName->setIconSize(QSize(50,50));
In Designer Click on your QToolbar and set iconSize.
Just stumbled across this after all these years. I remember I had this problem once and now again. This time I actually managed to solve it somewhat. It IS kinda weird tho and should receive some love at least documentation-wise.
The key is: You need to style QMenu AND QMenu::item If you just set the icon size via:
QMenu {icon-size: 40px;}
it will remain ignored until you also set something like
QMenu::item {background: transparent;}
Unfortunately this resets the menu stylesheet and you need to do something about the hover state to make it usable. But well.
Seems this works for me.
(also posted this on the qt forums)

How to disable minimizing by taskbar icon click

I've stumbled across very strange behaviour during work on my program.
I've written custom changeEvent class, which allows me to hide program to SysTray on minimizing.
But when i double click on taskbar app icon, the function goes crazy. It creates 2 to 4 systray icons and on requesting window show again, it just shows main window borders without any content inside.
Here's my changeEvent code:
void MainWindow::changeEvent(QEvent *e) {
QMainWindow::changeEvent(e);
if(e->type()==QEvent::WindowStateChange)
if(isMinimized()) {
trayIcon=new QSystemTrayIcon(QIcon(":/icon/itime.ico"));
connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(on_show(QSystemTrayIcon::ActivationReason)));
QAction *showAction=new QAction("Pokaż",trayIcon);
connect(showAction,SIGNAL(triggered()),this,SLOT(on_show()));
QMenu *trayIconMenu=new QMenu;
trayIconMenu->addAction(showAction);
trayIcon->setContextMenu(trayIconMenu);
trayIcon->show();
this->hide();
}
}
on_show(QSystemTrayIcon::ActivatioReason) SLOT:
void MainWindow::on_show(QSystemTrayIcon::ActivationReason reason) {
if(reason) {
if(reason!=QSystemTrayIcon::DoubleClick)
return;
}
if(this->isMinimized()) {
this->raise();
this->showNormal();
this->setWindowState(Qt::WindowActive);
trayIcon->hide();
}
}
on_show() SLOT is just the same besides that first if.
Soo, I would like to know whether there is any way to disable minimizing of window by taskbar icon click.
If there's none, then maybe you have any ideas what can go wrong in here when doubleclicking on icon in taskbar?
Thanks for help!
I've managed to work around that problem by overloading closeEvent function and leaving alone changeEvent function.
So, I'm using boolean flag to distinct between closing of program by menu item and by clicking "X" button and the rest stays just the same, as posted in my earlier post with one change.
I've moved this whole block of code to window constructor in order to prevent multiple creation of trayIcon, as pointed out by Nicolas.
trayIcon=new QSystemTrayIcon(QIcon(":/icon/itime.ico"));
connect(trayIcon,SIGNAL(activated(QSystemTrayIcon::ActivationReason)),this,SLOT(on_show(QSystemTrayIcon::ActivationReason)));
QAction *showAction=new QAction("Pokaż",trayIcon);
connect(showAction,SIGNAL(triggered()),this,SLOT(on_show()));
QMenu *trayIconMenu=new QMenu;
trayIconMenu->addAction(showAction);
trayIcon->setContextMenu(trayIconMenu);
Thanks for your help!

CCCallFunc: Selector not being called in inherited class

I'm trying to schedule selectors with CCCallFunc but the selector isn't getting called.
This works:
[self launchCreature];
This does not:
id launchCreatureAction = [CCCallFunc actionWithTarget:self selector:#selector(launchCreature)];
[self runAction:launchCreatureAction];
launchCreature is defined in the parent class, and the CCCallFunc works when used in the parent class. Nothing is showing up in the debugger when I run the action; it just doesn't run the code. (It never hits the breakpoint I have defined at the first line of launchCreature.)
Am I missing about something about how to use CCCallFunc, or how self works in subclasses?
Edit: I misremembered how my code is set up. launchCreature and the code above are BOTH defined in the parent class. The difference between working and not working is that it worked in an instance of the parent class, but doesn't work in an instance of the subclass. This no longer seems to work in the parent class either. Sorry for the confusion.
It works for me. You could try making a call to [super launchCreature] in [self launchCreature] in the subclass and see if the break point is being hit.

How do I properly set up generic QT actions for a menu constructed at run time?

I am populating a sytem tray icon menu (QMenu) from entries in an xml file which is read when my application starts up.
I am unsure of how to properly set up the SLOT end of the action:
QList<CMenuItem> menuItems = m_layout->getMenuItems();
QListIterator<CMenuItem> iter(menuItems);
while (iter.hasNext())
{
CMenuItem menuItem = iter.next();
QAction *action = new QAction(menuItem.qsTitle, this);
connect(action, SIGNAL(triggered()), this, SLOT(launchMenuItem()));
trayIconMenu->addAction(action);
}
How does my "launchMenuItem()" SLOT know which menu item was triggered? I can't make a SLOT for each menu item as I don't know how many items will exist until run time.
I can think of some ugly ways to do this, but I am looking for the RIGHT way.
What I usually do is to use QAction::setData(const QVariant&) to store whatever action ID I need. Then on slot side I retrieve ID with QAction::data() and behave accordingly.
Note that QVariant obviously accepts much more than basic int (which is what I use to identify actions), you can pass any QVariant-compatible info.
edit : oh! btw, this is somehow ugly because I make use of QObject::sender() to cast triggered action back. Sorry for that, but it works anyway.

How to prioritize touches for my CCMenu?

I have two CCMenu instances. At some point in the game, menu A is overlapped by menu B. However, when I press a button within menu B, the one that "gets it" is menu A.
How can I give touch priority to CCMenu B?
I tried this:
[[CCTouchDispatcher sharedDispatcher] setPriority:-130 forDelegate:menuB];
However, Xcode says that this delegate (menuB) was not found.
Okay, I fixed this, but I still think there should be a better way.
First, we have to edit CCMenu's interface. We have to create a new integer property.
#interface CCMenu : CCLayer <CCRGBAProtocol>
{
tCCMenuState state_;
CCMenuItem *selectedItem_;
GLubyte opacity_;
ccColor3B color_;
int extraTouchPriority; // Our new integer
}
#property (readwrite) int extraTouchPriority;
Now change the registerWithTouchDispatcher method to this:
-(void) registerWithTouchDispatcher
{
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:kCCMenuTouchPriority - extraTouchPriority swallowsTouches:YES];
}
Done. Now, when you have to give your CCMenu instance more priority than others, just give a higher extraTouchPriority value to it after initializing it.
I had the same problem. What i did is copied the entire CCMenu from cocos2d library, renamed it and then modified kCCMenuTouchPriority to what i wanted. Note that you have to rename kCCMenuTouchPriority for the custom menu. I used kkCCMenuTouchPriority.
I called it in code like this:
CCMenuPopUp *menu =[CCMenuPopUp menuWithItems:item1,nil];
I tried to subclass it but i ran into some problems and gave up and gone with the solution above.
the CCTouchDispatcher thing doesn't work because the menu isn't inited yet when you call it
Here's anoter variation on one of the anwers above, which doesn't alter the cocos2D code base, because that is bad practice: https://gist.github.com/tudormunteanu/6174624