How to create QToolBar in QWidget? - c++

I am trying to add a QToolBar in a QWidget. But I want its functionality to work as if it was a QMainWindow.
Apparently I can not create QToolBar in a QWidget, and using setAllowedAreas does not work with QWidget : it only works with QMainWindow. Also, my QWidget is in a QMainWindow.
How can I create a QToolBar for my widget?

The allowedAreas property only works when the toolbar is the child of a QMainWindow. You can add the toolbar to a layout, but it won't be movable by the user. You can still relocate it programmatically, however.
To add it to a layout for a fictional class inheriting QWidget:
void SomeWidget::setupWidgetUi()
{
toolLayout = new QBoxLayout(QBoxLayout::TopToBottom, this);
//set margins to zero so the toolbar touches the widget's edges
toolLayout->setContentsMargins(0, 0, 0, 0);
toolbar = new QToolBar;
toolLayout->addWidget(toolbar);
//use a different layout for the contents so it has normal margins
contentsLayout = new ...
toolLayout->addLayout(contentsLayout);
//more initialization here
}
Changing the toolbar's orientation requires the additional step of calling setDirection on the toolbarLayout, e.g.:
toolbar->setOrientation(Qt::Vertical);
toolbarLayout->setDirection(QBoxLayout::LeftToRight);
//the toolbar is now on the left side of the widget, oriented vertically

QToolBar is a widget. That's why, you can add a QToolBar to any other widget by calling addWidget for layout or by setting the QToolBar parent to your widget.
As you can see in documentation of QToolBar setAllowedAreas method:
This property holds areas where the toolbar may be placed.
The default is Qt::AllToolBarAreas.
This property only makes sense if the toolbar is in a QMainWindow.
That's why it is impossible to use setAllowedAreas if toolbar is not in QMainWindow.

As far as I know, the only way to properly use the toolbar is with the QMainWindow.
If you want to use the full functionality of the toolbar, create a mainwindow with the window flag Widget. This way you can add it inside some other widget without having it displayed as a new window:
class MyWidget : QMainWindow
{
public:
MyWidget(QWidget *parent);
//...
void addToolbar(QToolBar *toolbar);
private:
QMainWindow *subMW;
}
MyWidget::MyWidget(QWidget *parent)
QMainWindow(parent)
{
subMW = new QMainWindow(this, Qt::Widget);//this is the important part. You will have a mainwindow inside your mainwindow
setCentralWidget(QWidget *parent);
}
void MyWidget::addToolbar(QToolBar *toolbar)
{
subMW->addToolBar(toolbar);
}

Related

How do I make a QWidget automatically scale vertically to it's contents?

I've made a QT Designer Form called DropDownMenu. Essentially it is just a QWidget with a QVBoxLayout inside of it.
DropDownMenu has a function that pragmatically adds buttons to it.
QPushButton* DropDownMenu::AddButton(
const QString& text)
{
QPushButton* new_button = new QPushButton(text, this);
m_ui->LayoutManager->addWidget(new_button);
return new_button;
}
I then add a QWidget to my MainWindow inside of QT Designer & promote this widget to DropDownMenu. Then I add buttons to this new QWidget using the AddButton function.
The end result looks like this...
I want to make it so the containers scale according to how many buttons or widgets are placed inside of the layout, but they seem to just get squeezed together so that they fit the parents default size.
How can I make it so the parent scales to the size of all it's children?

Qt QWidget::setGeomerty

i'm stuck with a simple Function of Qt that does not work for me.i made a class that inherits
from QMainWindow and another class that inherits from QWidget.then i made from the second a member object(a pointer to) inside the first and assigned it as its centralWidget during the construction of my window.
when it comes to adjust my centraWidget inside the window with the function QWidget::setGeomerty() it simply don't work.here's my code:
void MainWindow::show()
{
//some code that centers my window on the screen
int margin=this->width()/7;
centralWidget()->setGeometry(margin,centralWidget()->geometry().top(),this->width()-margin,centralWidget()->geometry().bottom());
QMainWindow::show();
}
i know it might be stupid but i just can't figure it out.help me.
QMainWindow has its own layout in which the center area is occupied by the central widget. So it won't be pretty straightforward to break that layout and modify the central widget size / position arbitrarily.
What I recommend is to use a placeholder central widget and add your widget as a child.
I'm pretty sure you can achieve what you want by setting a proper Qt built in layout to the "placeholder" central widget and then adding your widget to the layout.
layouts was necessary to manage what i want; i think it's not possible to hand directly over the central widget and try to move/resize it;but by adding a layout and a child widget, we can dispose of them.here is my code:
mainwindow.cpp
// i focused on my window constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
m_MainView(new MainView(this)),
m_WindowLayout(new MainWindLayout(NULL))//my custom layout witch just inherits from QGridLayout
{
//.............
setCentralWidget(m_MainView);
m_WindowLayout=new MainWindLayout(m_MainView);//my layout set into my central Widget"m_MainView".
QWidget *temp(dynamic_cast<QWidget *>(m_MainView->centralView()));//centralView() returns a child QWidget of my central Widget
QMargins margins(this->width()/5,0,this->width()/5,0);//setting up layout margins :left,top,right,bottom;exactly what i need
m_WindowLayout->setContentsMargins( margins);
m_WindowLayout->addWidget(temp,0,0,-1,-1);//adding my child widget to the layout filling all cells of the gridlayout.
}
thanks everybody

Can you add a toolbar to QDialog?

I'm working on a project that needs to call a modal window with a toolbar to do some work on some data before it's loaded. The reason I need the toolbar is the user has a few different possible options that can be combined.
The obvious choice here is a Modal dialog (which I have working right now). The issue is I want a toolbar. This is a two part question:
Is it possible to add a toolbar to a QDialog? (also is it possible to do this in Qt Designer?)
If 1. is not possible, how can I make a QMainWindow modal?
You can simply use the setMenuBar function of the layout manager that is installed on your QDialog:
myDialog->layout()->setMenuBar(myMenuBar);
If you don't need the built-in drag and drop feature of QMainWindow's toolbars, you can simply add a QToolBar to any layout, including QDialog's layout(). See the DigviJay Patil's answer below for details, which is definitely cleaner conceptually.
Otherwise, please read on.
It is not directly possible to add a QToolBar to a QDialog in the QMainWindow::addToolBar() sense, because QDialog inherits only QWidget and not QMainWindow, as you noted (hence do not have the method addToolBar())
You can't make a QMainWindow modal, but you can insert a QMainWindow in a QDialog this way:
Code:
MyDialog::MyDialog() :
QDialog()
{
QMainWindow * mainWindow = new QMainWindow(); // or your own class
// inheriting QMainWindow
QToolBar * myToolBar = new QToolBar();
mainWindow->addToolBar(myToolBar);
QHBoxLayout * layout = new QHBoxLayout();
layout->addWidget(mainWindow);
setLayout(layout);
}
Indeed, a QMainWindow doesn't necessarily have to be a top-level widget, and you can even insert several QMainWindows as children of a single widget (may not be the wisest choice though, as the user would probably be confused with the separate sets of menu bars, toolbars, dock widgets, etc.).
You can add QToolBar in QDialog. But as a QWidget. Please have a look
MyDialog::MyDialog(QWidget *parent) : QDialog(parent)
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
QToolBar *toolBar = new QToolBar();
mainLayout->addWidget(toolBar);
QAction *action1 = new QAction("Add", toolBar);
QAction *action1 = new QAction("Del", toolBar);
//Add What you want
}
As QToolBar is child of QWidget we can add it as Widget. Using Layout you can adjust its position. Please check this link http://developer.nokia.com/community/wiki/How_to_use_QToolBar_and_QToolButton_in_Qt

Draggable QWidget

I have a MainWindow.cpp class with multiple images displayed that emit a clicked() signal. Once clicked on I want to open a widget that's a fixed size inside MainWindow and I want this widget to be able to be dragged around as long as it stays inside the MainWindow class.
I was looking at example code to try and write this widget class, in particular the Qt MainWindow Example. However, once one of the dockwindows are dragged around the display the Operating System specific titlebar (which lets you maximize, minimize, and close the window) gets displayed. I do not want this titlebar to be displayed.
How would I go about creating this class of draggable widgets?
Check setTitleBarWidget
Setting to a void widget will work:
It is not possible to remove a title bar from a dock widget.
However, a similar effect can be achieved by setting a default constructed QWidget
as the title bar widget.
Edit:
By request:
yourDockableWidget->setTitleBarWidget( new QWidget( yourDockableWidget ) );
In the example you are following, you could do it in constructor:
ColorSwatch::ColorSwatch(const QString &colorName, QWidget *parent, Qt::WindowFlags flags)
: QDockWidget(parent, flags)
{
/*...*/
setTitleBarWidget( new QWidget( this ) );
/*...*/
}
Now your widget wont have SO titlebar when undocked;

Setting a QDialog to be an alien

In a standalone GUI application where I don't have a windowmanager nor a composite manager I want to display a QDialog to the user to ask for values.
The dialog is quite big, so I want to make it translucent so that the user can look through it to see what happens in the application while the dialog is shown.
The problem is that for translucency of X native windows, there needs to be a composite manager. Qt internal widgets can be painted translucent because they don't correspond to native X windows (aliens) and are completely only known to Qt.
Is there a way to make the background of a QDialog translucent without having a composite manager running? Perhaps making it a normal child widget/alien of the application's main window? Is there a better alternative to this?
I don't know of any way of turning a QDialog into a normal child widget. Looking at the Qt for X11 code, I can't figure out a way of not setting the Qt::WindowFlags passed to the QWidget (parent) constructor so that it would be a plain widget and not a window of its own (but I could be wrong, didn't spend a lot of time on that).
A simple alternative is to use a plain QWidget as your container, instead of a QDialog. Here's a sample "PopupWidget" that paints a half-transparent-red background.
#include <QtGui>
class PopupWidget: public QWidget
{
Q_OBJECT
public:
PopupWidget(QWidget *parent): QWidget(parent)
{
QVBoxLayout *vl = new QVBoxLayout;
QPushButton *pb = new QPushButton("on top!", this);
vl->addWidget(pb);
connect(pb, SIGNAL(clicked()), this, SLOT(hide()));
}
public slots:
void popup() {
setGeometry(0, 0, parentWidget()->width(), parentWidget()->height());
raise();
show();
}
protected:
void paintEvent(QPaintEvent *)
{
QPainter p(this);
QBrush b(QColor(255,0,0,128));
p.fillRect(0, 0, width(), height(), b);
}
};
To show it, call it's popup() slot which will raise it to the top of the widget stack, make it as large as its parent, and show it. This will mask all the widgets behind it (you can't interact with them with the mouse). It hides itself when you click on that button.
Caveats:
this doesn't prevent the user from using Tab to reach the widgets underneath. This could be fixed by toggling the enabled property on your "normal" widget container for example. (But don't disable the PopupWidget's parent: that would disable the popup widget itself.)
this doesn't allow for a blocking call like QDialog::exec
the widgets in that popup won't be transparent, you'd have to create custom transparent-background versions for all the widget types you need AFAIK.
But that's probably less of a hassel than integarting a compositing manager in your environment.