PDA

View Full Version : contextmenu in QDockWidget title



klipko
4th March 2008, 00:07
I'm working on implementing floating / docking behavior for QDockWidget but when it's floating contextMenuEvent is no longer received so now the user can't right and select Dockable option. QDockWidget is subclassed and from there three different dock widgets inherit from that. The handling of contextMenuEvent is in the QDockWidget subclass.

Any ideas why this is happening? My goal is to implement something similar to Visual Studio were the user can right click on the title to Float or Dock the window. Side question: Is it possible to have contextMenu work on the title of a dockwidget?

Thank you

Using QT: 4.3.2

coderbob
4th March 2008, 11:36
I tested some code myself and it still uses the context menu when floating. Are you sure you are using a contextmenu from the dockwidget and not inheriting one from the mainwindow? When the dock is floating it will lose the one from the mainwindow since it is no longer the parent.

Can you post some code?

Bob

klipko
4th March 2008, 18:55
He is some code:

- MyDockWidget.h


#ifndef MYDOCKWIDGET_H
#define MYDOCKWIDGET_H

#include <QDockWidget>
class QMenu;
class QAction;

class MainWindow;

class MyDockWidget: public QDockWidget
{
Q_OBJECT;

public:
MyDockWidget(MainWindow * mainWindow, std::string const & title);
virtual ~MyDockWidget(void);

private:
void contextMenuEvent(QContextMenuEvent *e);

private slots:
void onFloat();
void onDock();

private:
QMenu *m_actionMenu;

QAction *m_actionFloat;
QAction *m_actionDock;
};

#endif


-- MyDockWidget.cpp


#include "MyDockWidget.h"
#include "MainWindow.h"

#include <QSettings>
#include <QContextMenuEvent>
#include <QMenu>
#include <QAction>


MyDockWidget::MyDockWidget(MainWindow * mainWindow, std::string const & title)
: QDockWidget(title.c_str(), mainWindow, 0)
{
std::string group = "gui/dock/";
group += windowTitle().toStdString();

setObjectName(windowTitle() + "_view");

m_actionMenu = new QMenu();

m_actionFloat = new QAction(tr("Floating"), mainWindow);
m_actionFloat->setCheckable(true);
connect(m_actionFloat, SIGNAL(triggered()), this, SLOT(onFloat()));
m_actionMenu->addAction(m_actionFloat);

m_actionDock = new QAction(tr("Dock"), mainWindow);
m_actionDock->setCheckable(true);
connect(m_actionDock, SIGNAL(triggered()), this, SLOT(onDock()));
m_actionMenu->addAction(m_actionDock);
}

MyDockWidget::~MyDockWidget(void)
{
}

void MyDockWidget::contextMenuEvent(QContextMenuEvent *e)
{
m_actionMenu->exec(e->globalPos());
}

void MyDockWidget::onFloat()
{
setFloating(true);
setAllowedAreas(Qt::NoDockWidgetArea);
m_actionFloat->setChecked(true);
m_actionDock->setChecked(false);
}

void MyDockWidget::onDock()
{
setAllowedAreas(Qt::AllDockWidgetAreas);
m_actionFloat->setChecked(false);
m_actionDock->setChecked(true);
}

All DockWidgets in the application inherit from MyDockWidget.

coderbob - You mention that when the dock is floating it will lose the contextMenuEvent from the parent. Does this mean I'll need to put in a contextMenuEvent in each class the inherits from MyDockWidget?

coderbob
6th March 2008, 07:29
I believe if you are going to subclass you should not be declaring


private:
void contextMenuEvent(QContextMenuEvent *e);


but instead


protected:
void contextMenuEvent(QContextMenuEvent *e);


And why are you parenting your QAction to the QMainWindow and not the QDockWidget?

Not sure but floating the widget and having the actions parents set to mainwindow could be causing problems.

Bob

klipko
7th March 2008, 23:32
I don't know why I parented the actions on mainwindow. Think it was an over site.

I sat down and made a few changes after re-re-reviewing the documentation and got something working for the most part. I still can get it into the mode were it will not display the menu when floating which is not good at all... but it works. The ultimate goal is to have the menu show when the user right clicks the mouse when over the title bar (docked or floating).



#ifndef VIEW_H
#define VIEW_H

#include <QDockWidget>
class QMenu;
class QAction;

class MainWindow;

class View : public QDockWidget
{
Q_OBJECT;

public:
View(MainWindow * mainWindow, std::string const & title);
virtual ~View(void);

private slots:
void onFloat();
void onDock();
void contextMenu(QPoint const & point);

private:
QMenu *m_actionMenu;

QAction *m_actionFloat;
QAction *m_actionDock;

};

#endif





#include "View.h"

#include "MainWindow.h"

#include <QMenu>
#include <QAction>
#include <QContextMenuEvent>

View::View(MainWindow * mainWindow, std::string const & title)
: QDockWidget(title.c_str(), mainWindow, 0)
{
std::string group = "gui/dock/";
group += windowTitle().toStdString();

setObjectName(windowTitle() + "_view");

m_actionMenu = new QMenu();

m_actionFloat = new QAction(tr("Floating"), this);
m_actionFloat->setCheckable(true);
connect(m_actionFloat, SIGNAL(triggered()), this, SLOT(onFloat()));
m_actionMenu->addAction(m_actionFloat);

m_actionDock = new QAction(tr("Dock"), this);
m_actionDock->setCheckable(true);
connect(m_actionDock, SIGNAL(triggered()), this, SLOT(onDock()));
m_actionMenu->addAction(m_actionDock);

setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(QPoint const &)),
this, SLOT(contextMenu(QPoint const &)));
}

View::~View(void)
{
std::string group = "gui/dock/";
group += windowTitle().toStdString();
}

void View::contextMenu(QPoint const & point)
{
m_actionMenu->exec(mapToGlobal(point));
}

void View::onFloat()
{
setFloating(true);
setFeatures(QDockWidget::DockWidgetFloatable);
setAllowedAreas(Qt::NoDockWidgetArea);
m_actionFloat->setChecked(true);
m_actionDock->setChecked(false);
}

void View::onDock()
{
setFeatures(QDockWidget::AllDockWidgetFeatures);
setAllowedAreas(Qt::AllDockWidgetAreas);
m_actionFloat->setChecked(false);
m_actionDock->setChecked(true);
}