[Solved] setToolTip in QAction menu
-
I have some menu items (menus QActions) I need them to tell the function the user to set the tooltip setToolTip (), but the tips do not appear. Searching the net found some answers saying it is normal because you do not use tooltips for menus.
Is it really normal?
You can not set tootip for menus in Qt?In the survey found a solution, but not quite understand how to implement it, just understand that you must override the QEvent:: Tooltip and intercept the event.
"Your text to link here...":http://www.qtcentre.org/threads/534-Tooltips-on-QActions
Could someone explain me this tip, preferably with a example code?
Thanks!
ps Sorry for the grammar, I am Brazilian and I'm using google translator.
-
Matheus,
Feel free to join us in the "Brazilian group":http://developer.qt.nokia.com/groups/qt_brazil and to post your questions in the associated "forum":http://developer.qt.nokia.com/forums/viewforum/34 , where you can write in Portuguese.
The solution proposed in that QtCentre thread you mentioned is something like this:
@
// Subclass QMenuBar
class MyMenuBar : public QMenuBar
{
public:
MyMenuBar(QWidget * parent = 0)
: QMenuBar(parent) {}// reimplement the method event() virtual bool event (QEvent * e) { QMenuBar::event(e); const QHelpEvent *helpEvent = static_cast<QHelpEvent *>(e); // Look for QEvent::ToolTip if (helpEvent->type() ==QEvent::ToolTip) { // "call QToolTip::showText on that QAction's tooltip." QToolTip::showText(helpEvent->globalPos(), activeAction()->toolTip()); } else { QToolTip::hideText(); } }
};
int main( int argc, char **argv )
{
QApplication app( argc, argv );
MyMenuBar *bar = new MyMenuBar;
QAction *action = bar->addAction("my action");
action->setToolTip("my tooltip");bar->show(); return app.exec();
}
@DevNet colleagues, any better solution? :-)
-
I created my own version of QMenuBar, but I'm having a lot of compilation errors.
,h
@#ifndef MODQMENUBAR_H
#define MODQMENUBAR_H#include <QMenuBar>
class ModQMenuBar : QMenuBar
{public:
ModQMenuBar(QWidget *parent=0);virtual bool event(QEvent *);
}
#endif // MODQMENUBAR_H@
.cpp
@#include "ModQMenuBar.h"
#include <QHelpEvent>
#include <QToolTip>
ModQMenuBar::ModQMenuBar(QWidget *parent):QMenuBar(parent)
{
ModQMenuBar::event(QEvent *evt)
{
QMenuBar::event(evt);const QHelpEvent *helpevent = static_cast<QHelpEvent *>(e); if(helpevent->type() == QEvent.ToolTip) { QToolTip.showText(helpevent->globalPos(), activeAction()->toolTip()); } else { QToolTip.hideText(); } }
};@
error
@
/usr/include/QtCore/qcoreevent.h:53: error: expected initializer before ‘QtCoreModule’
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/ModQMenuBar.cpp:-1: In constructor ‘ModQMenuBar::ModQMenuBar(QWidget*)’:
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/ModQMenuBar.cpp:7: error: expected primary-expression before ‘*’ token
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/ModQMenuBar.cpp:7: error: ‘evt’ was not declared in this scope
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/ModQMenuBar.cpp:8: error: expected ‘;’ before ‘{’ token
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/ModQMenuBar.cpp:23: error: expected ‘}’ at end of input
@ -
I managed to settle in shares
lacked the ';' in the declaration of the class. h
I was defining the Event method in the class constructor.
Well now it is with the fixes that.
@#include "ModQMenuBar.h"
#include <QHelpEvent>
#include <QToolTip>ModQMenuBar::ModQMenuBar(QWidget *parent):QMenuBar(parent)
{}
ModQMenuBar::event(QEvent * evt)
{
QMenuBar::event(evt);const QHelpEvent *helpevent = static_cast<QHelpEvent *>(e); if(helpevent->type() == QEvent.ToolTip) { QToolTip.showText(helpevent->globalPos(), activeAction()->toolTip()); } else { QToolTip.hideText(); }
}@
.h
@#ifndef MODQMENUBAR_H
#define MODQMENUBAR_H#include <QMenuBar>
class ModQMenuBar : QMenuBar
{public:
ModQMenuBar(QWidget *parent=0);//virtual bool event(QEvent *);
};
#endif // MODQMENUBAR_H@
now to two errors
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/ModQMenuBar.cpp:10: error: ISO C++ forbids declaration of ‘event’ with no type
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/ModQMenuBar.cpp:10: error: no ‘int ModQMenuBar::event(QEvent*)’ member function declared in class ‘ModQMenuBar’
-
Except the constructor and destructor all the functions need to be defined with a return type. Of course any method defined in your implementation needs to be declared in the header.
Uncomment this line@ virtual bool event(QEvent *); @
Change the function in the .cpp to
@ bool ModQMenuBar::event(QEvent * evt) @
Maybe you also need a
@ #include <QEvent> @
That should fix the compilation.
-
Now is functioning
@#ifndef MODQMENUBAR_H
#define MODQMENUBAR_H#include <QMenuBar>
#include <QEvent>class ModQMenuBar : QMenuBar
{public:
ModQMenuBar(QWidget *parent=0);virtual bool event(QEvent *);
};
#endif // MODQMENUBAR_H
@.cpp
@#include "ModQMenuBar.h"
#include <QToolTip>
#include<QHelpEvent>ModQMenuBar::ModQMenuBar(QWidget *parent):QMenuBar(parent)
{}
bool ModQMenuBar::event(QEvent * evt)
{
const QHelpEvent *helpEvent = static_cast<QHelpEvent *>(evt);if(evt->type() == QEvent::ToolTip) { QToolTip::showText(helpEvent->globalPos(), activeAction()->toolTip()); } else { return QMenuBar::event(evt); } return true;
}
@Thanks to everybody who responded
-
I am now trying to set this menu bar modified to be the hem of my QMainWindow setMenuBar using the inherited method () but keep getting an error on the line where ModQMenuBar instantiate.
@ modmenubar = new ModQMenuBar(this);
setMenuBar(modmenubar); @I get an error that is inaccessible QWidget.
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/WindowMain.cpp:25: error: ‘QWidget’ is an inaccessible base of ‘ModQMenuBar’
-
In the declaration of ModQMenuBar you inherited QMenuBar, however did not make it public. In the line 7 of your header file, try the following:
@
class ModQMenuBar : public QMenuBar
@ -
Right... you're missing the "public" keyword. When you inherit from a class, you specify the type of inheritance. Mostly you would only need public inheritance, you could read up on private and protected inheritance if you want.
So it should be..
@ class ModQMenuBar : public QMenuBar @
[ Edit: We probably need a "svn update" functionality on the "reply page" :-P .. so we can update the post to see if it's been answered before committing the reply.. ]
-
Now produced another error
/usr/include/QtGui/qmenubar.h:340: error: ‘QMenuBar& QMenuBar::operator=(const QMenuBar&)’ is private
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/ModQMenuBar.h:8: error: within this context
/home/MatheusDevel/Devel/QtOptica/QtOptica-build-desktop/../QtOptica/WindowMain.cpp:25: synthesized method ‘ModQMenuBar& ModQMenuBar::operator=(const ModQMenuBar&)’ first required here
-
You wouldn't need to access the "=" operation of the menubar normally. So i in your code
@ modmenubar = new ModQMenuBar(this); @
modmenubar should a pointer to ModQMenuBar
@ ModQMenuBar* modmenubar; @
If that doesn't fix it.. could you post relevant code?
-
I declared in header
@#ifndef WINDOWMAIN_H
#define WINDOWMAIN_H#include <QMainWindow>
#include <QMdiArea>
#include "ModQMenuBar.h"class WindowMain : public QMainWindow
{
public:
WindowMain(QWidget *parent = 0);~WindowMain(); private: // Area MDI QMdiArea *mdiarea; // Menus QMenu *arquivos; QMenu *relatorios; QMenu *ferramentas; QMenu *fiscal; QMenu *moviment; QMenu *configura; QMenu *ajuda; QMenu *redundantes; QMenu *relgerencias; // QActions de menus QAction *clientes; QAction *produtos; QAction *forneced; QAction *represen; QAction *usuarios; QAction *medicos; QAction *sair; QAction *enderecos; QAction *marclente; QAction *matelente; QAction *tipopgto; QAction *tipolente; QAction *tratament; QAction *restricoes; QAction *autobackup; QAction *bdconexao; QAction *impressdoc; QAction *leiturax; QAction *reducaoz; QAction *configicms; QAction *manual; QAction *queisso; QAction *sobre; QAction *relvenda; QAction *relcaixa; QAction *relespelhos; QAction *relos; QAction *partmedica; QAction *partfuncio; QAction *fatumensal; QAction *fatudiario; QAction *ranklentes; QAction *rankfornec; QAction *orcamentos; QAction *devolucoes; QAction *movicaixa; QAction *ordemservic; QAction *vendas; QAction *contapagar; QAction *contarecebe; QAction *calcula; QAction *callenbord; QAction *compatarmlen; QAction *backup; ModQMenuBar modmenubar; // << << << << here
};
#endif // WINDOWMAIN_H
@ -
Now after posting the code here, I notice not defined as a pointer.
I had set as a stack variable.
Thanks !!!!!!!
@ModQMenuBar *modmenubar; // << << << << here@
-
Is compiling normally, but the tooltip does not yet appear.
I did a test by putting a message to display if the IF test is satisfied. The message is never shown, ie, the IF test is never satisfied.
@#include "ModQMenuBar.h"
#include <QToolTip>
#include <QHelpEvent>
#include <iostream>ModQMenuBar::ModQMenuBar(QWidget *parent):QMenuBar(parent)
{}
bool ModQMenuBar::event(QEvent * evt)
{
const QHelpEvent *helpEvent = static_cast<QHelpEvent *>(evt);if(helpEvent->type() == QEvent::ToolTip) { QToolTip::showText(helpEvent->globalPos(), activeAction()->toolTip()); std::cout << "Passou no IF"; // test if } return QMenuBar::event(evt);
}
@I'm setting the tooltip for the method by QActions setToolTip
@restricoes = new QAction("Restrinções", configura);
restricoes->setToolTip("Configura o acesso dos usuários ao sistema");
@ -
I've just tested the code you posted, the tooltip appears.
Remember, to see the tooltip you need to leave the mouse pointer stopped for a while over the menu item.
And try to use "qDebug()":http://doc.qt.nokia.com/4.7/qdebug.html instead of std::cout.
-
ok, I'll put here some of the code where I use the ModQMenuBar
@
#include <QRect>
#include <QMenuBar>
#include <QToolBar> // Cabeçalhos da API Qt que serão usadas na janela pincipal
#include <QStatusBar>
#include <QList>#include "WindowMain.h" // Usa o arquivo de cabeçalho onde a classe foi definida
/* Define a classe WindowMain e já invoca o
construtor da classe pai, passando o ponteiro
"parent" como parâmetro.*/WindowMain::WindowMain(QWidget *parent):QMainWindow(parent)
{
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); // Define os caracteres da
// aplicação p/ UTF-8setWindowTitle("TESTETSTETS"); modmenubar = new ModQMenuBar(this); setMenuBar(modmenubar); // Exibe a barra de status de QMainWindow statusBar()->show(); // Prepara a area de trabalho MDI da aplicação mdiarea = new QMdiArea; setCentralWidget(mdiarea); // Prepara o menu principal da aplicação configura = menuBar()->addMenu("&Configurações"); // Prepara os itens de menu restricoes = new QAction("Restrinções", configura); autobackup = new QAction("Backup Automático", configura); bdconexao = new QAction("Conexão com o BD", configura); impressdoc = new QAction("Impressão de Documentos", configura); // Configuração das dicas de ferramenta restricoes->setToolTip("Configura o acesso dos usuários ao sistema"); autobackup->setToolTip("Configura o backup automático do sistema"); bdconexao->setToolTip("Configura a conexão com o banco de dados"); // Carregando a lista de itens QList <QAction *> listconfig; listconfig << restricoes << autobackup << bdconexao << impressdoc;
//Adicionando a lista de intens aos menus
configura->addActions(listconfig);
// Deixando a janela no centro da tela
QRect ct = geometry();
ct.moveCenter(QApplication::desktop()->availableGeometry().center());
setGeometry(ct);}
WindowMain::~WindowMain()
{
delete mdiarea;
delete modmenubar;
}
@The header has already posted above
-
The current code handles QEvent::ToolTip in QMenuBar::event. For the menu items, you need to do the same QMenu::event().
Just a side note: As you can see, Qt does not support this use case by default. Do a quick research in your system, how many applications show tooltips like those you want? IMHO menu and menu items should have self-explaining names. If the menu names are good enough, the tooltips are redundant. But that's just my opinion...