Centering widgets in a dynamic layout? - qt

I'm using the answer to this SO question to make a custom image widget which automatically scales correctly. It works fine but now I am trying to center the image widget instance at the center of my main window.
My idea was to create a QHBoxLayout, add the image widget to that and then add the hBox instance to the ui->verticalLayout.
Doesn't work. The image still displays flush left with the error message: QLayout: Attempting to add QLayout "" to MainWindow "MainWindow", which already has a layout
I then tried a few variations on 'setAlignment` but then the image doesn't appear at all. My simple test code is below.
What am I missing here?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QPixmap pix;
pix.load("/Users/home/Desktop/test.jpg");
ImageLabel2* image = new ImageLabel2(this);
image->setPixmap(pix);
QHBoxLayout* hbox = new QHBoxLayout(this);
hbox->addWidget(image);
// hbox->setAlignment(image,Qt::AlignCenter);
hbox->setAlignment(Qt::AlignHCenter);
// ui->verticalLayout->addLayout(hbox);
ui->verticalLayout->addLayout(hbox);
// ui->verticalLayout->addWidget(image);
// ui->verticalLayout->setAlignment(image,Qt::AlignCenter);
// ui->verticalLayout->setAlignment(Qt::AlignHCenter);
}

Try this:
QHBoxLayout* hbox = new QHBoxLayout(this);
hbox->addStretch();
hbox->addWidget(image);
hbox->addStretch();

None of the suggestions here worked for me. Don't know why and it seems hard to debug layout problems
However a reply to my question on the Qt Project.org site works perfectly. So not my solution but I am posting it here since this "centering/resizing image" issue seems a common problem.
class CustomWidget : public QWidget {
public:
CustomWidget(const QPixmap &p, QWidget* parent = 0)
: QWidget(parent), pixmap(p) {}
void paintEvent(QPaintEvent * e)
{
QRect srcRect(QPoint(), pixmap.size());
QSize dstSize = srcRect.size().scaled(
e->rect().size(), Qt::KeepAspectRatio);
QRect dstRect(QPoint((width() - dstSize.width())/2,
(height() - dstSize.height())/2), dstSize);
QPainter p(this);
p.setRenderHint(QPainter::Antialiasing);
p.drawPixmap(dstRect, pixmap, srcRect);
}
private:
QPixmap pixmap;
};
and then in the main window:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(new CustomWidget(QPixmap("test.png")));
}

main window(QMainwindow) API setCentralWidget to align the widget on center.
Note:Concept of centrewidget, is to differentiate the docking area( Left, Right, Bottom, Top ).
with out a centre how some one know who is where. when we are developing with QMainWindow, you can see in UI_MainWindow.h, setting Centrewidget with dummy QWidget
Below code will work
#include "mainwindow.h"
#include <QLabel>
#include <QHBoxLayout>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindowClass)
{
ui->setupUi(this);
QPixmap pix;
pix.load("C:\\Users\\user\\Desktop\\Uninstallation failure2.png");
//Replace with ImageLabel2
QLabel* image = new QLabel(this);
image->setPixmap(pix);
QHBoxLayout* hbox = new QHBoxLayout(this);
hbox->addWidget(image);
QWidget* centreWidget = new QWidget();
//QMainwindow, having a feature called centreWidget, to set the layout.
centreWidget->setLayout( hbox );
setCentralWidget( centreWidget );
}
MainWindow::~MainWindow()
{
}

Related

Something seems wrong while dragging QSplitter?

A qsplitter has been used in my application, and OpaqueResize is set to 'false',while dragging the splitter handle, the widget becoming smaller is repainted continuously, this is not right. What I thought is that the QWidgets on both sides of the splitter handle should not receive any signals about repaint or resize until mouseRelease.This issue troubles me several days, if anyone knows about how to deal with it, please give me a hand, thank you.
Qt5.11.2 on Windows10 64-bits
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// left
ui->widget_2->bgColor = QColor(255,0,0);
ui->widget_2->tag = 0;
// right
ui->widget_3->bgColor = QColor(0,0,255);
ui->widget_3->tag = 1;
}
MainWindow::~MainWindow()
{
delete ui;
}
MyWidget::MyWidget(QWidget *parent) : QWidget(parent)
{
bgColor = QColor(255,255,255);
tag = 0;
}
void MyWidget::paintEvent(QPaintEvent *event)
{
QWidget::paintEvent( event );
QPainter painter(this);
QBrush brush( bgColor );
painter.fillRect( event->rect(), brush );
qDebug() << "paintEvent:tag="<<tag;
}

Qt placing widget on custom place

I need to place(programmaticaly) my custom widget in specified place in my MainWindow.
On screenshoot I've marked red rectangle "widget" on place where I want to place my widget. I want place widget on top of QmenuBar and QToolBar.
I've tried setCentralWidget, but it expands widget on whole window.
Image presenting my problem
Code of my widget:
timers.cpp
#include "QtWidgets"
#include "timers.h"
static QLabel *createDragLabel(const QString &text, QWidget *parent)
{
QLabel *label = new QLabel(text, parent);
label->setAutoFillBackground(true);
label->setFrameShape(QFrame::Panel);
label->setFrameShadow(QFrame::Raised);
return label;
}
Timers::Timers(QWidget *parent) : QWidget(parent)
{
QLabel *wordLabel = createDragLabel("dupppa", this);
}
mainwindow.cpp
MainWindow::MainWindow()
{
initMenu();
initButtons();
TrackWindow *trackWindow = new TrackWindow();
setCentralWidget(trackWindow);
Timers *firstTimer = new Timers();
//setCentralWidget(firstTimer); // suck
}
Ok, here is a solution: make MainWidget to be a parent of your widget but do not add it to parent layout. Then basically move your widget with QWidget::move() and and set its size with QWidget::resize(). This way you get a widget with absolute location.
An extract of working code:
#include <QLayout>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow{ parent },
ui{ new Ui::MainWindow }
{
ui->setupUi(this);
menuBar = new QMenuBar { this };
toolBar = new QToolBar { this };
textEdit = new QTextEdit { this };
menuBar->addMenu("File");
menuBar->addMenu("Edit");
menuBar->addMenu("About");
toolBar->addAction("Copy");
toolBar->addAction("Cut");
toolBar->addAction("Insert");
toolBar->addAction("Other tools");
layout()->setMenuBar(menuBar);
addToolBar(toolBar);
textEdit->setText("Your widget");
textEdit->resize(90, 30);
textEdit->move(250, 10);
}
A screenshot:

CentralWidget adjust size to show all the content

I'm a beginner with Qt and I haven't understand yet the layout on centralWidget.
I have a custom QWidget subclass (with a .ui and the cpp class) that I want to add to the central Widget.
I'd like to understand how to say to the QMainWindow subclass to resize and fit the content whenever I add something.
I've tried with adjustSize method both on mainwindow and on centralWidget objects but nothing change..
Anyway, I'm adding the widget in this way:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
MyWidget *w = new Undistort();
w->setParent(this->centralWidget());
}
some advice?
Given example, depending on Pixmap size, QMainWindow will resize. Generally this is not the ideal case, as a user MainWindow need to display on the desktop, It should not be more that your desktop screen size. I am not sure you are actually looking for this. Copied fromSO Ans
#include "mainwindow.h"
#include <QLabel>
#include <QHBoxLayout>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindowClass)
{
ui->setupUi(this);
QPixmap pix;
pix.load("C:\\Users\\user\\Desktop\\Uninstallation failure2.png");
//Replace with ImageLabel2
QLabel* image = new QLabel(this);
image->setPixmap(pix);
QHBoxLayout* hbox = new QHBoxLayout(this);
hbox->addWidget(image);
QWidget* centreWidget = new QWidget();
//QMainwindow, having a feature called centreWidget, to set the layout.
centreWidget->setLayout( hbox );
setCentralWidget( centreWidget );
}

showing hidden dockwidget in qt

hi i create a dockwidget which i am starting it as hidden. The problem is that afterwards i cannot show it, while i can get the status correctly from the isHidden() function. The weird thing is that if i start the dockwidget not hidden, it works perfect. I am including an example that reproduces this strange behaviour.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtGui>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void showDock();
private:
Ui::MainWindow *ui;
QDockWidget *dock;
QPushButton *button;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// QMainWindow mainWindow;
// QDockWidget *dock = new QDockWidget(&mainWindow);
QDialog *dockDialog = new QDialog(this); // <---------edit: you need to create a parent widget for the dock
dock = new QDockWidget(dockDialog);
dock->setStyleSheet("QDockWidget { font: bold }");
dock->setFloating(true);
dock->setFeatures(QDockWidget::DockWidgetVerticalTitleBar | QDockWidget::DockWidgetFloatable | QDockWidget::DockWidgetMovable);
QAbstractButton *floatButton = dock->findChild<QAbstractButton*>("qt_dockwidget_floatbutton");
if(floatButton)
floatButton->hide();
dock->setAllowedAreas( Qt::NoDockWidgetArea );
dock->setWindowTitle("Tools");
this->addDockWidget(Qt::TopDockWidgetArea, dock, Qt::Vertical);
QMainWindow *window = new QMainWindow(dock); // <------edit: set the dock to be the parent for the window
window->setWindowFlags(Qt::Widget);
QToolBar *bar = new QToolBar(window);
bar->setMovable(false);
bar->addAction("Select");
bar->addAction("Polygon");
bar->addAction("Brush");
bar->addAction("Erazer");
bar->addSeparator();
bar->addAction("Mark");
bar->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
bar->setOrientation(Qt::Vertical);
window->addToolBar(Qt::LeftToolBarArea, bar);
window->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
window->setParent(dock);
dock->setWidget(window);
dock->hide(); // <------------ comment this line and it will work, edit: you do not need to do that anymore, it is working nicely now
button = new QPushButton("show", this);
button->setCheckable(true);
QObject::connect(button, SIGNAL(clicked()), this, SLOT(showDock()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showDock()
{
// qDebug() << "hello";
if(button->isChecked()){
if(dock->isHidden()){
qDebug() << "hidden";
dock->setFloating(true); // <-----edit: you need to add these lines in order to be able to see the dialog that contains the dock widget, i do not know why i need to that again since in the initialization i already specifying that my dock is floatable
QAbstractButton *floatButton = dock->findChild<QAbstractButton*>("qt_dockwidget_floatbutton"); // <---------edit: add this lines in order to get rid off the floating button
if(floatButton)
floatButton->hide(); // <----edit: the same as previous
dock->show();
}
}
if(!button->isChecked()){
if(!dock->isHidden()){
qDebug() << "not hidden";
dock->hide();
}
}
}
as it is now the above code the dockwidget is not appearing in the screen. If you try to comment the line that i am specifying in the mainwindow.cpp it works, but the point is that i want to start the dockwidget hidden. Does someone have any idea, of what is happening.
Thanks.
Parent of the QDock control should be your window widget, and not object of the MainWindow class.
So, you need to replace this:
dock = new QDockWidget(this);
with this:
QMainWindow *window = new QMainWindow(0); // I smell a potential leak here (set the parent!)
dock = new QDockWidget(window);
Control is visible when you press Show button in the first case, too, but it is somewhere outside the window, so you may not see it. Also, there is no need to create separate instance of QMainWindow inside class that is already inheriting QMainWindow.
I see you show()/hide() your dockwidget. I haven't tried it myself but maybe you should hide and show the dockwdiget with the QDockWidget::toggleViewAction method.

How to display a widget inside a main window

I have a project marines and i have the following files structure.
marines.pro
FORMS
iran.ui
marines.h
Headers
iran.h
marines.h
Sources
iran.cpp
main.cpp
marines.cpp
I added the widget iran in the project marines.
Here is marines.cpp
#include <QtGui>
#include "marines.h"
#include "iran.h"
marines::marines(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::marines)
{
ui->setupUi(this);
connect(ui->actionExit, SIGNAL(triggered()), this, SLOT(close()));
connect(ui->actionIran, SIGNAL(triggered()), this, SLOT(ir()));
}
void marines::ir()
{
//slot to display iran ui inside my main window
}
marines::~marines()
{
delete ui;
}
and here is my iran.cpp
#include "iran.h"
#include <QtGui>
iran::iran(QWidget *parent) :
QWidget(parent),
ui(new Ui::iran)
{
ui->setupUi(this);
}
iran::~iran()
{
delete ui;
}
How can i display the widget iran i made in qt designer?.
It all depends on how you want the widget to be displayed.
you could add a layout to your central widget in your MainWindow and add your custom widget to the layout
if you want your custom widget to be centralWidget of the MainWindow then use setCentralWidget
If you want the custom widget as a subWindow then add MdiArea to your MainWindow. Then add custom widget to you MdiArea.
If you just want the custom widget to be displayed as a window then just "widget.show()"
Its better to look at Qt's examples to understand how a MainWindow is used.
marines::marines(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::marines)
{
ui->setupUi(this); // after this
iran *ir = new iran(); // create variable ir
ir->show(); // show window
...
}

Resources