I'm quite new to qt and c++ and I've encountered a problem that I can't seem to figure out. I'm wanting to open a frameless and transparent window when I click a button on the main ui. I've got the code working to open a new window when I press a button on the main ui but I can't seem to get the frameless and transparent part working.
Here is the source codes for the small program that I wrote to learn this
main.cpp
#include "learnwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
LearnWindow w;
w.show();
return a.exec();
}
Here is the LearnWindow.h
#ifndef LEARNWINDOW_H
#define LEARNWINDOW_H
#include <QMainWindow>
#include <transwindow.h>
namespace Ui {
class LearnWindow;
}
class LearnWindow : public QMainWindow
{
Q_OBJECT
public:
explicit LearnWindow(QWidget *parent = 0);
~LearnWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::LearnWindow *ui;
TransWindow *winTrans;
public slots:
void openTrans();
};
#endif // LEARNWINDOW_H
Here is learnwindow.cpp
#include "learnwindow.h"
#include "ui_learnwindow.h"
LearnWindow::LearnWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::LearnWindow)
{
ui->setupUi(this);
}
LearnWindow::~LearnWindow()
{
delete ui;
}
void LearnWindow::openTrans()
{
winTrans = new TransWindow (this);
//winTrans->setWindowTitle("NewWin");
// winTrans->setWindowFlags(Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint);
//winTrans->setAttribute(Qt::WA_TranslucentBackground,true);
//winTrans->setAutoFillBackground(false);
//winTrans->setStyleSheet("background:transparent;");
winTrans->show();
}
void LearnWindow::on_pushButton_clicked()
{
openTrans();
}
Here is the transwindow.h
#ifndef TRANSWINDOW_H
#define TRANSWINDOW_H
#include <QDialog>
namespace Ui {
class TransWindow;
}
class TransWindow : public QDialog
{
Q_OBJECT
public:
explicit TransWindow(QWidget *parent = 0);
//setWindowFlags(windowFlags()| Qt::FramelessWindowHint);
~TransWindow();
private:
Ui::TransWindow *ui;
};
#endif // TRANSWINDOW_H
And here is transwindow.cpp
#include "transwindow.h"
#include "ui_transwindow.h"
TransWindow::TransWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::TransWindow)
{
//setWindowTitle("NewWin");
//setWindowFlags(Qt::FramelessWindowHint);
//setAttribute(Qt::WA_TranslucentBackground,true);
ui->setupUi(this);
}
TransWindow::~TransWindow()
{
delete ui;
}
In the different source codes you'll see commented out lines which is the different things that I've tried. For the most part the problem is, if I un-comment out any of the lines that try to set the "Qt::FramlessWindowHint" the program runs normally but never opens a new window when I click the button on the main ui.
If I un-comment out any of the lines where I set the "Qt::WA_TranslucentBackground" the new window will open up when when the button is pressed in the main ui but the background of the new window is black, not transparent.
Other info that may be pertinent:
linux: ubunto 12.04
qt 5.0.2 (64-bit)
qt creator 2.7.1
Try this:
setWindowFlags(Qt::Widget | Qt::FramelessWindowHint);
setParent(0); // Create TopLevel-Widget
setAttribute(Qt::WA_NoSystemBackground, true);
setAttribute(Qt::WA_TranslucentBackground, true);
setAttribute(Qt::WA_PaintOnScreen); // not needed in Qt 5.2 and up
Related
Normally, moving a QDialog using QDialog::move() positions the dialog outside of taskbars.
However, on Ubuntu 20.04 with two monitors it is not the case with frameless Dialogs :
This does not happen if the dialog is not frameless :
This behaviour has been observed on Ubuntu 20.04. It also happens only under some configurations :
Main monitor needs to be on the right side, with task bar on the left (between the two monitors)
Left monitor needs to have a lower resolution than the right one
Fractional scaling needs to be disabled
Here is the code for a minimally reproducible example used in the screenshots:
#ifndef BUGDIALOG_H
#define BUGDIALOG_H
#include <QDialog>
namespace Ui {
class BugDialog;
}
class BugDialog : public QDialog
{
Q_OBJECT
public:
explicit BugDialog(QWidget *parent = nullptr);
~BugDialog();
private slots:
void on_moveButton_clicked();
private:
Ui::BugDialog *ui;
};
#endif // BUGDIALOG_H
#include "bugdialog.h"
#include "ui_bugdialog.h"
BugDialog::BugDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::BugDialog)
{
ui->setupUi(this);
ui->xPosEdit->setText("3200");
ui->yPosEdit->setText("1000");
}
BugDialog::~BugDialog()
{
delete ui;
}
void BugDialog::on_moveButton_clicked()
{
int x = ui->xPosEdit->text().toInt();
int y = ui->yPosEdit->text().toInt();
if (x > -1 && x > -1)
move(x, y);
}
The main window is less interesting, it only creates the child window controlling its WindowFlags property :
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "bugdialog.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
void on_framelessBox_stateChanged(int arg1);
private:
void hideDialog();
Ui::MainWindow *ui;
BugDialog* dialog;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
dialog = new BugDialog(nullptr);
dialog->hide();
}
MainWindow::~MainWindow()
{
delete ui;
delete dialog;
}
void MainWindow::on_pushButton_clicked()
{
if (dialog->isHidden())
{
dialog->show();
ui->pushButton->setText("Hide dialog");
}
else
{
hideDialog();
}
}
void MainWindow::on_framelessBox_stateChanged(int)
{
auto windowType = ui->framelessBox->isChecked() ? Qt::FramelessWindowHint : Qt::Dialog;
dialog->setWindowFlags(windowType);
hideDialog();
}
void MainWindow::hideDialog()
{
dialog->hide();
ui->pushButton->setText("Show dialog");
}
This looks like a bug in Qt. Does anyone know if it is expected behaviour? Or how to get around this?
I didn't find a proper solution or satisfying workaround for this issue, but found a partial solution that is half satisfying :
Before each move() on the dialog, set its flag to Qt::Window (no frameless) and hide it.
Override the moveEvent() handler, set the window flag to Qt::FramelessWindowHint and show it.
Here are the two changes I made on this example :
void BugDialog::on_moveButton_clicked()
{
int x = ui->xPosEdit->text().toInt();
int y = ui->yPosEdit->text().toInt();
if (x > -1 && x > -1)
{
hide();
setWindowFlags(Qt::Window);
move(x, y);
}
}
void BugDialog::moveEvent(QMoveEvent *)
{
QTimer::singleShot(500, this, [this](){
this->setWindowFlags(Qt::FramelessWindowHint);
this->show();
});
}
I also tried changing the dialog painting. The idea was to set window flags as a "framefull" dialog but paint the dialog as if it had the FramelessWindowHint flag. I found no acceptable/affordable solution with this idea.
I'd like to process the stream of my webcam frame by frame with QT6. I've checked the internet but since QTMultimedia was heavily reworked with QT6, and since QT6 is pretty new, all the documentation/questions available are outdated.
So, In order to achieve my goal, I'm using a QMediaCaptureSession with a camera set on QMediaDevices::defaultVideoInput(). I checked that this was working by setting the video output of the QMediaCaptureSession to a QVideoWidget with m_session.setVideoOutput(ui->videowidget);, and it's working fine, except that I can't process the frames (basically, it's rendering my webcam on the QVideoWidget).
Now, to process the frames, I have to use a QVideoSink as far as I understand the documentation here and there. So I replaced m_session.setVideoOutput(ui->videowidget); with m_session.setVideoSink(&mysink);, where mysink is a QVideoSink.
Then, since I want to process the frames, I'm connecting the videoFrameChanged signal of mysink to a function processVideoFrame where I want to do 2 things :
process the current frame
render the result on the UI, ideally on ui->videowidget
This is the point where I'm struggling. I do not understand how to use the paint function of the class QVideoFrame to render the processed frame on the QVideoWidget. More precisely :
I do not understand how I'm supposed to instantiate the QPainter. I tried a straightforward new QPainter(ui->videowidget) but it ends up in a QWidget::paintEngine: Should no longer be called exception and nothing is rendered
I do not understand what is actually representing the second parameter rect of QVideoFrame::paint?
I made a MWE, code is below.
mwe_videosinkpainting.h
#ifndef MWE_VIDEOSINKPAINTING_H
#define MWE_VIDEOSINKPAINTING_H
#include <QMainWindow>
#include <QMediaCaptureSession>
#include <QMediaDevices>
#include <QCamera>
#include <QVideoSink>
#include <QPainter>
QT_BEGIN_NAMESPACE
namespace Ui { class MWE_VideoSinkPainting; }
QT_END_NAMESPACE
class MWE_VideoSinkPainting : public QMainWindow
{
Q_OBJECT
public:
MWE_VideoSinkPainting(QWidget *parent = nullptr);
~MWE_VideoSinkPainting();
private slots:
void processVideoFrame();
private:
Ui::MWE_VideoSinkPainting *ui;
QVideoSink mysink;
QMediaCaptureSession m_session;
QScopedPointer<QCamera> m_camera;
};
#endif // MWE_VIDEOSINKPAINTING_H
mwe_videosinking.cpp
#include "mwe_videosinkpainting.h"
#include "ui_mwe_videosinkpainting.h"
MWE_VideoSinkPainting::MWE_VideoSinkPainting(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MWE_VideoSinkPainting)
{
ui->setupUi(this);
m_camera.reset(new QCamera(QMediaDevices::defaultVideoInput()));
m_session.setCamera(m_camera.data());
//m_session.setVideoOutput(ui->videowidget);
connect(&mysink, &QVideoSink::videoFrameChanged, this, &MWE_VideoSinkPainting::processVideoFrame);
m_session.setVideoSink(&mysink);
m_camera->start();
}
MWE_VideoSinkPainting::~MWE_VideoSinkPainting()
{
delete ui;
}
void MWE_VideoSinkPainting::processVideoFrame()
{
QVideoFrame videoframe = mysink.videoFrame();
if(videoframe.map(QVideoFrame::ReadOnly))
{
//This is the part I'm struggling to understand and achieve
videoframe.paint(new QPainter(ui->videowidget), QRectF(0.0f,0.0f,100.0f,100.0f), QVideoFrame::PaintOptions());
videoframe.unmap();
}
}
main.cpp
#include "mwe_videosinkpainting.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MWE_VideoSinkPainting w;
w.show();
return a.exec();
}
ui_mwe_videosinkpainting.h (just so that you have the whole code, it has no value for the question)
#ifndef UI_MWE_VIDEOSINKPAINTING_H
#define UI_MWE_VIDEOSINKPAINTING_H
#include <QtCore/QVariant>
#include <QtMultimediaWidgets/QVideoWidget>
#include <QtWidgets/QApplication>
#include <QtWidgets/QGridLayout>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MWE_VideoSinkPainting
{
public:
QWidget *centralwidget;
QGridLayout *gridLayout;
QVideoWidget *videowidget;
QHBoxLayout *horizontalLayout;
QMenuBar *menubar;
QStatusBar *statusbar;
void setupUi(QMainWindow *MWE_VideoSinkPainting)
{
if (MWE_VideoSinkPainting->objectName().isEmpty())
MWE_VideoSinkPainting->setObjectName(QString::fromUtf8("MWE_VideoSinkPainting"));
MWE_VideoSinkPainting->resize(800, 600);
centralwidget = new QWidget(MWE_VideoSinkPainting);
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
gridLayout = new QGridLayout(centralwidget);
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
videowidget = new QVideoWidget(centralwidget);
videowidget->setObjectName(QString::fromUtf8("videowidget"));
horizontalLayout = new QHBoxLayout(videowidget);
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
gridLayout->addWidget(videowidget, 0, 0, 1, 1);
MWE_VideoSinkPainting->setCentralWidget(centralwidget);
menubar = new QMenuBar(MWE_VideoSinkPainting);
menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 800, 21));
MWE_VideoSinkPainting->setMenuBar(menubar);
statusbar = new QStatusBar(MWE_VideoSinkPainting);
statusbar->setObjectName(QString::fromUtf8("statusbar"));
MWE_VideoSinkPainting->setStatusBar(statusbar);
retranslateUi(MWE_VideoSinkPainting);
QMetaObject::connectSlotsByName(MWE_VideoSinkPainting);
} // setupUi
void retranslateUi(QMainWindow *MWE_VideoSinkPainting)
{
MWE_VideoSinkPainting->setWindowTitle(QCoreApplication::translate("MWE_VideoSinkPainting", "MWE_VideoSinkPainting", nullptr));
} // retranslateUi
};
namespace Ui {
class MWE_VideoSinkPainting: public Ui_MWE_VideoSinkPainting {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MWE_VIDEOSINKPAINTING_H
The answer is quite straightforward : you can use setVideoSink AND setVideoOutput.
The code I gave in OP is good, you just have to uncomment setVideoOutput(ui->videowidget); of mwe_videosinking.cpp and to call setVideoSink BEFORE calling setVideoOutput
Since I cannot format code in a comment...
So, you mean change this...
ui->setupUi(this);
m_camera.reset(new QCamera(QMediaDevices::defaultVideoInput()));
m_session.setCamera(m_camera.data());
//m_session.setVideoOutput(ui->videowidget);
connect(&mysink, &QVideoSink::videoFrameChanged, this, &MWE_VideoSinkPainting::processVideoFrame);
m_session.setVideoSink(&mysink);
m_camera->start();
...to this?
ui->setupUi(this);
m_camera.reset(new QCamera(QMediaDevices::defaultVideoInput()));
m_session.setCamera(m_camera.data());
m_session.setVideoSink(&mysink);
m_session.setVideoOutput(ui->videowidget);
connect(&mysink, &QVideoSink::videoFrameChanged, this, &MWE_VideoSinkPainting::processVideoFrame);
m_camera->start();
I did this and I am still only getting black in my videoWidget.
New to C++ and Qt as part of a research project (biology) and have been struggling with presumably some quite simple stuff. I'd really appreciate someone's help.
I'm working with a GUI for a pre-existing programme and I'm trying to transfer a QString variable from the QLineEdit of one of the windows (inputform), to the QLineEdit of a second window (output form).
The bit I'm stuck with is that I need the output form to appear, with it's LineEdit pre-populated, when I click a button on a third window (filedialog).
Problem:
At start up --> two windows appear: filedialog and inputform.
User enters data into inputform's QLineEdit
User presses 'transferButton' on filedialog window
On button press --> outputform appears, with a QLineEdit pre-populated with the user's data (from the inputform).
I assume the problem is of the getter/setter variety and my variable is probably going out of scope, but I've tried following lots of similar examples but can't make it work.
Thanks in advance.
Here's my code:
Main.cpp
#include "filedialog.h"
#include "inputform.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FileDialog w;
InputForm w2;
w.show();
w2.show();
return a.exec();
}
filedialog.h
#ifndef FILEDIALOG_H
#define FILEDIALOG_H
#include <QDialog>
namespace Ui {
class FileDialog;
}
class FileDialog : public QDialog
{
Q_OBJECT
public:
explicit FileDialog(QWidget *parent = nullptr);
~FileDialog();
void setFileName();
QString getFileName();
private slots:
void on_transferButton_clicked();
private:
Ui::FileDialog *ui;
QString fileName;
};
#endif // FILEDIALOG_H
filedialog.ccp
#include "filedialog.h"
#include "ui_filedialog.h"
#include "inputform.h"
#include "ui_inputform.h"
#include "outputform.h"
#include "ui_outputform.h"
FileDialog::FileDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::FileDialog)
{
ui->setupUi(this);
}
FileDialog::~FileDialog()
{
delete ui;
}
void FileDialog::setFileName()
{
InputForm *inputform = new InputForm;
fileName = inputform->ui->inputLineEdit->text();
}
QString FileDialog::getFileName()
{
return fileName;
}
void FileDialog::on_transferButton_clicked()
{
setFileName();
OutPutForm *outputform = new OutPutForm;
outputform->ui->outputLineEdit->setText(getFileName());
outputform->show();
}
inputform.h
#ifndef INPUTFORM_H
#define INPUTFORM_H
#include <QWidget>
namespace Ui {
class InputForm;
}
class InputForm : public QWidget
{
Q_OBJECT
public:
explicit InputForm(QWidget *parent = nullptr);
~InputForm();
Ui::InputForm *ui;
};
#endif // INPUTFORM_H
inputform.ccp
#include "inputform.h"
#include "ui_inputform.h"
InputForm::InputForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::InputForm)
{
ui->setupUi(this);
}
InputForm::~InputForm()
{
delete ui;
}
outputform.h
#ifndef OUTPUTFORM_H
#define OUTPUTFORM_H
#include <QWidget>
namespace Ui {
class OutPutForm;
}
class OutPutForm : public QWidget
{
Q_OBJECT
public:
explicit OutPutForm(QWidget *parent = nullptr);
~OutPutForm();
Ui::OutPutForm *ui;
};
#endif // OUTPUTFORM_H
outputform.ccp
#include "outputform.h"
#include "ui_outputform.h"
OutPutForm::OutPutForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::OutPutForm)
{
ui->setupUi(this);
}
OutPutForm::~OutPutForm()
{
delete ui;
}
Thank you for your brief pointer.
After some playing around:
Setup mainwindow (or in my case main dialog window). Generate inputform instance, connect button to inputform.
FileDialog::FileDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::FileDialog)
{
ui->setupUi(this);
InputForm *inputForm = new InputForm;
connect(ui->transferButton,SIGNAL(clicked()),inputForm,SLOT(getLineEditTextFunc()));
inputForm->show();
}
FileDialog::~FileDialog()
{
delete ui;
}
void FileDialog::on_transferButton_clicked()
{
}
Then from the input form:
Define a function to get the input form's LineEdit text (fileName); and then also generate an output form and populate it's LineEdit with the fileName variable.
InputForm::InputForm(QWidget *parent) :
QWidget(parent),
ui(new Ui::InputForm)
{
ui->setupUi(this);
}
InputForm::~InputForm()
{
delete ui;
}
void InputForm::getLineEditTextFunc()
{
fileName = this->ui->inputLineEdit->text();
OutPutForm *outputform = new OutPutForm;
outputform->ui->outputLineEdit->setText(fileName);
outputform->show();
}
In a Qt/C++ piece of code, I have a QTabWidget class with different tabs.
I would like to add a last "+" tab, so when the user is clicking on it, I create a new tab.
However I would like to have all my tabs closable ('x' at the right of the tab), except the last one where I don't want the 'x' to be displayed. How can I have this granularity in the closable flag ?
Surprised to see that this is not yet answered. Had some time and I have implemented a working example. Note that instead of using one of the tabs as your "+" button, I have used QToolButton thereby making it simpler to make tabs closable with QTabWidget::setTabsClosable(bool)
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTabWidget>
#include <QToolButton>
#include <QLabel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
QTabWidget* _pTabWidget;
private slots:
void slotAddTab();
void slotCloseTab(int);
};
#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);
_pTabWidget = new QTabWidget(this);
this->setCentralWidget(_pTabWidget);
// Create button what must be placed in tabs row
QToolButton* tb = new QToolButton(this);
tb->setText("+");
// Add empty, not enabled tab to tabWidget
_pTabWidget->addTab(new QLabel("Add tabs by pressing \"+\""), QString());
_pTabWidget->setTabEnabled(0, false);
// Add tab button to current tab. Button will be enabled, but tab -- not
_pTabWidget->tabBar()->setTabButton(0, QTabBar::RightSide, tb);
// Setting tabs closable and movable
_pTabWidget->setTabsClosable(true);
_pTabWidget->setMovable(true);
connect(tb,SIGNAL(clicked()),this,SLOT(slotAddTab()));
connect(_pTabWidget,SIGNAL(tabCloseRequested(int)),this,SLOT(slotCloseTab(int)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slotAddTab()
{
QWidget* newTab = new QWidget(_pTabWidget);
_pTabWidget->addTab(newTab, tr("Tab %1").arg(QString::number(_pTabWidget->count())));
_pTabWidget->setCurrentWidget(newTab);
}
void MainWindow::slotCloseTab(int index)
{
delete _pTabWidget->widget(index);
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
I am attempting to create a custom widget. My Widget renders itself unless it is inside a scroll area. The code below works. If I change the if(0) to an if(1) inside the MainWindow constructor, it will not render the "Hello World" string. I assume that I must (re)implement some additional methods, but so far I have not been able to find the correct ones with trial and error.
// hellowidget.h
#ifndef HELLOWIDGET_H
#define HELLOWIDGET_H
#include <QtGui>
class HelloWidget : public QWidget
{
Q_OBJECT
public:
HelloWidget(QWidget *parent = 0);
void paintEvent(QPaintEvent *event);
};
#endif // HELLOWIDGET_H
// hellowidget.cpp
#include "hellowidget.h"
HelloWidget::HelloWidget(QWidget *parent)
: QWidget(parent)
{
}
void HelloWidget::paintEvent(QPaintEvent *event)
{
QPainter painter(this);
painter.drawText(rect(), Qt::AlignCenter, "Hello World");
}
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private:
};
#endif // MAINWINDOW_H
// mainwindow.cpp
#include "mainwindow.h"
#include "hellowidget.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
HelloWidget *hello = new HelloWidget;
QWidget *central = hello;
if( 0 )
{
QScrollArea *scroll = new QScrollArea ;
scroll->setWidget(hello);
central = scroll;
}
setCentralWidget( central );
}
MainWindow::~MainWindow()
{
}
// main.cpp
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
You just have to give your HelloWidget a size and place.
Add this line to your code.
hello->setGeometry(QRect(110, 80, 120, 80));
Or if you want to fill the scroll area with your widget:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QScrollArea *const scroll(new QScrollArea);
QHBoxLayout *const layout(new QHBoxLayout(scroll));
HelloWidget *const hello(new HelloWidget);
hello->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
layout->addWidget(hello);
setCentralWidget( scroll );
}
Per Qt docs, "When using a scroll area to display the contents of a custom widget, it is important to ensure that the size hint of the child widget is set to a suitable value. If a standard QWidget is used for the child widget, it may be necessary to call QWidget::setMinimumSize() to ensure that the contents of the widget are shown correctly within the scroll area."
Does it work right if you follow these instructions?
I was pulling my hair out over this also, but eventually found QScrollArea's setWidgetResizable, which made the QScrollArea allow my widget to expand to take up the available space.