In my qt application, i have designed status bar with few icons. On the left of my status bar i have added menu icon (QPixmap) when i click that icon i need to show a menu similar to PC start menu. I searched a lot but i did not found Qwidget for this.
This is my qt application window
As per my recent comment i added my edited code below since i cannot add the code in comment section, plz suggest a solution
//Menu Button
menuBtn->setIcon(QPixmap(":/new/prefix1/ic_menu_black.png"));
statusBar()->addWidget(menuBtn);
connect(menuBtn,SIGNAL(clicked(bool)),this,SLOT(showPopupMenu()));
void MainWindow::showPopupMenu(){
QMenu qMenuStart;
QAction qCmdStart1(QString::fromUtf8("Product Details"), &qMenuStart);
qMenuStart.addAction(&qCmdStart1);
QAction qCmdStart2(QString::fromUtf8("Memory Status"), &qMenuStart);
qMenuStart.addAction(&qCmdStart2);
QObject::connect(&qCmdStart1, &QAction::triggered,[](bool){
qDebug() << "Product Details triggered"; }
);
QObject::connect(&qCmdStart2, &QAction::triggered,[](bool){
qDebug() << "Memory Status triggered"; }
);
qMenuStart.exec();
menuBtn->setMenu(&qMenuStart);
qMenuStart.show();
qMenuStart.popup(mapToGlobal(pos() - QPoint(0, qMenuStart.height())));
qDebug()<<"Menu Clicked!";
}
popup menu on click of menu button
I took your sample code and changed it to illustrate what I described in my latest comments:
Add a member variable to the
MainWindow
declaration:The changed sample code:
Note:
I set
menuBtn
as parent of themenuStart
. Thus,menuBtn
should manage the destruction ofmenuStart
when it is destroyed itself.The signal handler becomes shorter respectively:
I did it carefully but couldn't test it (as it's no MCVE). So, please, take this with a "grain of salt".
Note:
I just realized that you use the "pre-Qt5" style of connecting signal handlers. Qt5 introduced a nice extension to its signals supporting function pointers as well as method pointers. Due to this, I was able to do the signal handlers simply as lambdas. (The lambdas are these
[](bool){/*...*/}
I connected to the action slots. I was always suspicious about these new lambdas until I realized that they are an excellent tool to write very simple adapters for signal handlers as well as to make quite compact sample code.)Update about Lambdas:
The brackets
[]
can be used to add variables to the environment (or context) of the lambda. If it is empty (as I used it) only global variables and functions can be used. Using[this]
means the currentthis
pointer is added to the environment. Thus, the lambda may access member variables of the current class instance.When I recognized lambdas the first time, I saw often
[=]
meaning the lambda gets the current context of the calling function (e.g. copies of every local function variable). I personally consider this as dangerous, especially for signal handlers. I will elaborate this a little bit:The environment of a lambda allows to access "variables from outside" in the lambda body. Variables may be added by value or by reference. If a variable is provided by reference, it may be accessed in the lambda body but it will not grant that the life-time of the "outside" variable is long enough. (If it is not it results in a "dangling reference" with the same Undefined Behavior like a dangling pointer.) Does it help to prevent references at all? No. It is fine for primitive types (e.g.
int
orfloat
) but could be inefficient (or even semantically wrong) for objects. Using pointer to objects instead, is as dangerous as using references. Thus, the enviroment of a lambda should be used with care.As a rule of thumb, I personally use the following method to implement lambdas: I always start with an empty environment (
[]
). If I recognize a variable which I need in the lambda I add it to the environment whereby I consider its sufficient lifetime (or look for an alternative).Update:
As I'm a personal fan of SVG, I prepared a (similar) menu icon as SVG file:
You may save this in a text file
ic_menu_black.svg
and try to load it in your app.Qt's importer has unfortunately only limited support of SVG. Thus, not every trick which is possible in SVG will work correctly in Qt. Therefore, I modified a copy of an icon out of our Qt application to be sure that this will work.
Reading your question, I was not quite sure what your actual problem is. Unfortunately, due to the security policy of our company,
i.stack.imgur.com
is blocked and I'm just in the office. Probably, your snapshot had clarified the things for me. (I could have a look at it when I'm home again.)However, out of curiosity, I tried my luck and want to show what I've got:
Actually, it is quite easy to add a widget to a status bar using
QStatusBar::insertPermanentWidget()
.Unfortunately, permanent widgets are placed on the right. If the requirement (to place it at left) is essential, this can be tweaked by nesting two status bars into each other. (Actually, every other layout should be capable also but the
QMainWindow::setStatusBar()
requires aQStatusBar*
.)The inner status bar is the one which has to be used for temporary messages. To prevent the funny effect of duplicated size grips, the size grip is disabled for the inner status bar (using
QStatusBar::setSizeGripEnabled()
).Another side effect of nested status bars is the visualization of separators at the left and right of the inner status bar. I considered this as not that bad (concerning the aesthetical aspect) and didn't care about it.
May be, I could have used simply a
QLabel
(instead of the inner status bar) for message display (losing the additional capabilities provided byQStatusBar
e.g. the timeout for auto-clear of a message).To provide the start button, I originally used a
QPushButton
. Remembering that I have to place the start menu somehow I replaced it with aQToolBar
as it may contain aQAction
which in turn is ready equipped to manage a sub-menu.As I got this working I realized the indicator which appeared at the start button when I set the menu. To keep the sample as short as possible I decided to live with this for now.
After having some communication with the questioner, I added an alternative implementation using a class derived from
QLabel
. The menu placement has to be done on its own. But finally, it's not that complicated...The 2nd version is activated if
USE_LABEL
is defined (near beginning of source code).My sample
testQStartBtn.cc
:I compiled with VS2013 and Qt5.6 on Windows 10 (64 bit). This is how it looks:
The updated version with the derived
QLabel
looks like this: