Qt: Creating button on QGraphicsItem - c++

I have QGraphicsScene and QGraphicsView. I'm adding QGraphicsRectItem to scene and I've encounter some difficulties...
I want to create button on my Item. I've tried to create QPushButton but when I used show() method it appears in new window. I've also tried do another QGraphicsRectItem that could be button, but I don't know how to place it in my QGraphicsRectItem that is placed on scene.

Related

How to create QToolBar in QWidget?

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);
}

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;

QMainWindow centralWidget border

I have a QMainWindow whose central widget has been set to a QGraphicsView viewing a black scene (for test purposes). Note that in the code below, I use my class derived from QGraphicsView, called CQtGlView, which reimplements only the resizeEvent function.
Regardless of whether I add the view directly,
CQtMainWindow::CQtMainWindow() {
m_glView = new CQtGlView();
setCentralWidget(m_glView);
}
or stick it in a layout with margins of 0 in a dummy widget,
CQtMainWindow::CQtMainWindow() {
m_glView = new CQtGlView();
QWidget* dummy = new QWidget();
QHBoxLayout* l = new QHBoxLayout();
l->setContentsMargins(0,0,0,0);
l->addWidget(m_glView);
dummy->setLayout(l);
setCentralWidget(dummy);
}
I get an unwanted grey border around the widget.
The screenshot below illustrates the problem, visible between my scene and the windows aero border.
This would not be a problem if my application did not allow switching to full screen. The border is very obvious once the rest of the screen is black.
It's possible this area represents the DockWidgetAreas around the outside of the central widget.
Is there anything I can do to solve this other than not use QMainWindow? (Undesirable due to my use of menuBar, tool bars, and statusBar.)
It turns out that QGraphicsView derives from QFrame, where I assumed it was only a QWidget.
The solution to this problem was to call setFrameStyle(QFrame::NoFrame); in the constructor of my QGraphicsView subclass. Or if it was not a subclass,
m_glView->setFrameStyle(QFrame::NoFrame);
Have you tried setFrameShape(QFrame::NoFrame) on the QGraphicsView?

Viewing entire QGraphicsScene

I'm trying to write a map editor in Qt, using QGraphicsView and QGraphicsScene for both the map and tile sheets.
The problem I'm having right now is with making a good widget for importing tiles. For this, I'm using a QTabWidget (for different tile sheets), and TileWidget as the widget for each tab, which contains the QGraphicsScene and QGraphicsView.
It's working to a rough degree, but not all the tiles (or TileObjects, which are implementations of QGraphicsItem) are visible. I'm even calling view->ensureVisible(scene->sceneRect()), but still not all of the QGraphicsScene is not visible, even with scroll bars.
I understand this is due to limiting the maximum size of my QTabWidget, but that is necessary.
This happens mainly when I import a larger tile sheet.
I have a TileWidget as the QWidget for the QTabWidget, which has both the QGraphicsScene and the QGraphicsView.
TileWidget::TileWidget(QWidget *parent)
: QWidget(parent)
{
scene = new QGraphicsScene;
view = new TileView(scene, this);
connect(view, SIGNAL(newBrushSelected(TileObject *b)), this, SLOT(selectNewBrush(TileObject *b)));
}
TileView is simply a QGraphicsView re-implemented to handle mouse release events.
To add tiles, I simply call scene->addItem().
I have no other code for TileView. When I use
void TileWidget::showEvent(QShowEvent *event)
{
view->fitInView(scene->itemsBoundingRect(), Qt::KeepAspectRatio);
}
I get something like this.
It's okay for smaller tile sheets, but not for larger ones. What should I add to keep the size of the tiles normal, and navigate TileView using scroll bars?
Nevermind, figured it out. Just me being stupid.
You need something like:
p_myGraphicsView->fitInView(
myGraphicsView->scene()->itemsBoundingRect(),
Qt::KeepAspectRatio);

Qt add Widget to GraphicsView?

Is there a way to draw Widgets on QGraphicsView instead of QGraphicsScene so that the widget stays in position when the scene is moved?
I want to create some dialogs that are dockable inside the workspace like this:
http://www.thebandfrom.com/wp-content/uploads/photoshop-ui.png
You can use the addWidget function of QGraphicsScene, and then set the QGraphicsItem::ItemIgnoresTransformations flag to the added QGraphicsProxyWidget.
QGraphicsProxyWidget* proxyWidget = scene->addWidget(myWidget);
proxyWidget->setFlag(QGraphicsItem::ItemIgnoresTransformations);
You can add widgets onto the QGraphicsView directly by setting the QGraphicsView as their parent. You could also add a layout so that when the QGraphicsView is resized, your widgets arrange themselves appropriately.