How to Fit ScrollArea into Grid in QT? - qt

How to Fit ScrollArea into Grid in QT ?
I want to apply QScrollArea to this part of the grid which contains first name, lastname...

Here is the sample. The size of QScrollArea is changed inside QGridLayout.
header file
#ifndef WIDGET_H
#define WIDGET_H
#include <QtGui/QWidget>
#include <QScrollArea>
#include <QTextEdit>
#include <QPushButton>
#include <QGridLayout>
class Widget: public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
private:
QScrollArea *sca;
QTextEdit *txt;
QPushButton *btn;
private slots:
void onClicked();
};
#endif // WIDGET_H
source file
#include "widget.h"
#include <QScrollBar>
Mediator::Widget(QWidget *parent)
: QWidget(parent)
{
sca = new QScrollArea(this);
txt = new QTextEdit;
txt->setFixedSize(1000,500);
btn = new QPushButton("Button",this);
btn->setFixedSize(75,30);
QGridLayout *layout = new QGridLayout;
layout->addWidget(sca);
layout->addWidget(btn);
sca->setWidget(txt);
setLayout(layout);
connect(btn,SIGNAL(clicked()),this,SLOT(onClicked()));
}
Widget::~Widget()
{
}
void Widget::onClicked()
{
txt->setText(txt->toPlainText() + "abcd ");
}

QScrollArea is an ordinary widget and its size is controlled by the layout that contains it. You can change it size by calling its resize method.
However if you need the object contaied in QScrollArea to be resized as well than you should use QScrollArea::widgetResizable property. Take a look at Image Viewer example to see how the QLabel is resized along with QScrollArea.

Related

How can I access the content of a widget outside the constructor?

I want to display the content I wrote in the QLineEdit widget after clicking on the QPushButton with the function ShowMessage(). How can I access that content outside of the constructor?
Tried putting the QLineEdit object I created in to a private variable.
My CPP file
#include "manualwidget.h"
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QHBoxLayout>
#include <QMessageBox>
ManualWidget::ManualWidget(QWidget *parent) : QWidget(parent)
{
QLabel *label = new QLabel(this);
QLineEdit *lineEdit = new QLineEdit(this);
QPushButton *pushButton = new QPushButton(this);
QHBoxLayout *layout = new QHBoxLayout();
label->setText("Enter text:");
pushButton->setText("Ok");
layout->addWidget(label);
layout->addWidget(lineEdit);
layout->addWidget(pushButton);
setLayout(layout);
connect(pushButton,SIGNAL(clicked()),this ,SLOT(showMessage()));
connect(lineEdit, SIGNAL(returnPressed()),this, SLOT(showMessage()));
}
void ManualWidget::showMessage(){
QMessageBox::information(this, "Message", "The text entered in the "
"manual widget window is:\n" + m_lineEdit->text());
}
My header file
#ifndef MANUALWIDGET_H
#define MANUALWIDGET_H
#include <QWidget>
#include <QLineEdit>
class ManualWidget : public QWidget
{
Q_OBJECT
public:
explicit ManualWidget(QWidget *parent = nullptr);
signals:
public slots:
private slots:
void showMessage();
private:
QLineEdit m_lineEdit;
};
#endif // MANUALWIDGET_H
#eyllanesc suggestion might work, but it should not be a prefered approach. Qt has its' own memory model, and usage of it should be prefered. Thus, "QLineEdit m_lineEdit" should be changed to e.g. "QLineEdit* m_lineEdit", and in constructor you should initialize it in the following way:
// Instance of the QLineEdit will be owned by the ManualWidget which is part of Qt memory management now.
m_lineEdit = new QLineEdit(this);
Then, the following line:
layout->addWidget(lineEdit);
Can be changed to:
layout->addWidget(m_lineEdit);
Why is it bad to use "QLineEdit m_lineEdit"? Because Qt might want to destroy this object for some reason (you still can call m_lineEdit.deleteLater()) and you might end up in the "double destruction" situation which would result in app being crashed. You can say that in this way conflicting memory models would interact.

Image not displaying using QPainter drawImage

I have an QFrame within a QWidget, in my application. When I try to draw a draw a image within the QFrame, the image is inserted only when coordinates are (0,0) and if they are something like (100,100) the image is not drawn. I created a new class for the frame and implemented paintEvent(QPaintEvent *p) in it. Is there any thing I am doing here ?
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QFrame>
#include <QPainter>
#include "frame.h"
class frame;
namespace Ui {
class Widget;
}
class Widget : public QFrame
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
frame * f;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QFrame(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
f = new frame(ui->frame);
f->show();
}
Widget::~Widget()
{
delete ui;
}
frame.h
#ifndef FRAME_H
#define FRAME_H
#include <QObject>
#include <QWidget>
#include <QPainter>
class frame : public QWidget
{
Q_OBJECT
public:
explicit frame(QWidget *parent = 0);
protected:
void paintEvent(QPaintEvent *p);
signals:
public slots:
};
#endif // FRAME_H
frame.cpp
#include "frame.h"
frame::frame(QWidget *parent) : QWidget(parent)
{
}
void frame::paintEvent(QPaintEvent *p)
{
QPainter* pPainter = new QPainter(this);
QImage img(":/left.png");
Q_ASSERT(!img.isNull());
QRect source(0,0,20,10);
QRect target(50,50,20,10);
pPainter->drawImage(target, img,source);
QWidget::paintEvent(p);
QWidget::update();
}
If I use QRect target(0,0,20,10) in the above code the image is drawn.
testImage.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = testImage
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += main.cpp\
widget.cpp \
frame.cpp
HEADERS += widget.h \
frame.h
FORMS += widget.ui
RESOURCES += \
src.qrc
DISTFILES +=
I am being stuck in this one for a long time, any idea will be helpful. I have tried Qt verions 5.6 and 5.8, similar result. And the OS is Lubuntu. The image resolution is 20*10. Thanks.enter image description here
Try like this:
void frame::paintEvent(QPaintEvent *p){
QPainter lPainter(this);
QPixmap lPixmap(":/left.png");
Q_ASSERT(!lPixmap.isNull());
QRect source(0,0,20,10);
QRect target(50,50,20,10);
lPainter->drawPixmap(target, lPixmap);
QWidget::paintEvent(p);}
remove update form painEvent and try to use pixmap.
I have found a solution, I have subclassed QgraphicsView and reimplemented paint method in it,
void graphicsView::paintEvent(QPaintEvent *e)
{
QGraphicsView::paintEvent(e);
QPainter pPainter(this->viewport());
QImage img(":/images/x.png");
Q_ASSERT(!img.isNull());
QRect target(300,230,20,10);
pPainter.drawImage(target, img);
}

Connecting buttons to mainwindows slot

I tried to do a bunch of research on how to solve this problem, and everything is slightly different than my situation, or didn't work to fix my problem. I will start off by explaining my main goal. I have a main window with 7 buttons on it(amongst other things), when you hit each button, it closes out the current window and opens up a new window. All the windows will have the same 7 buttons, so you can go between each window. With all windows having the exact same 7 buttons, I wanted to set up a function that each class can call to set up each button and connect to a slot() in my mainwindow.cpp(called setupSubsystemButtons in example below). The actual buttons are being placed there, but they only work when pressed from my mainwindow.cpp....when I press them from a different class nothing happens.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtWidgets>
#include <QDialog>
namespace Ui {
class MainWindow;
}
class MainWindow : public QDialog
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
QWidget *window;
void setupSubsystemButtons(QGridLayout *layout);
~MainWindow();
private:
Ui::MainWindow *ui;
QLineEdit *tempValueBox;
QLineEdit *humidityValueBox;
QLineEdit *c02ValueBox;
...
public slots:
void ECSgeneralScreen();
void homeScreen();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "ecsgeneralcommand.h"
#include <QtWidgets>
#include <QtCore>
MainWindow::MainWindow(QWidget *parent) : QDialog(parent)
{
QGridLayout *layout = new QGridLayout;
...
setLayout(layout);
}
void MainWindow::ECSgeneralScreen()
{
ECSgeneralCommand *ECSgeneral = new ECSgeneralCommand;
this->close();
ECSgeneral->show();
//opens up the ECS screen
}
void MainWindow::homeScreen()
{
MainWindow *home = new MainWindow;
this->close();
home->show();
//opens up the home screen
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setupSubsystemButtons(QGridLayout *layout)
{
//Push Button Layout
homeScreenButton = new QPushButton("Home");
layout->addWidget(homeScreenButton, 3, 11);
connect(homeScreenButton, SIGNAL(clicked()), this, SLOT(homeScreen()));
ECSgeneralScreenButton = new QPushButton("General");
layout->addWidget(ECSgeneralScreenButton,5,11);
connect(ECSgeneralScreenButton, SIGNAL(clicked()), this, SLOT(ECSgeneralScreen()));
}
ecsgeneralcommand.h
#ifndef ECSGENERALCOMMAND_H
#define ECSGENERALCOMMAND_H
#include <QDialog>
#include <QMainWindow>
#include <QtWidgets>
#include <QObject>
#include "mainwindow.h"
class ECSgeneralCommand : public QDialog
{
Q_OBJECT
public:
explicit ECSgeneralCommand(MainWindow *parent = 0);
private:
...
public slots:
};
#endif // ECSGENERALCOMMAND_H
ecsgeneralcommand.cpp
#include "ecsgeneralcommand.h"
#include "mainwindow.h"
#include <QtWidgets>
#include <QtCore>
ECSgeneralCommand::ECSgeneralCommand(MainWindow *parent) : QDialog(parent)
{
QGridLayout *layout = new QGridLayout;
QWidget::setFixedHeight(600);
QWidget::setFixedWidth(550);
...
MainWindow setupButtons;
//Setup Subsystem Buttons
setupButtons.setupSubsystemButtons(layout);
setLayout(layout);
};
MainWindow setupButtons;
//Setup Subsystem Buttons
setupButtons.setupSubsystemButtons(layout);
This will create the buttons and connect their signals to slots of setupButtons, which will get deleted as soon as it's out of scope (the end of the ECSgeneralCommand constructor). So your buttons will be left connected to nothing.
You need to connect the button signals to an object that will exist at the time the button is pressed, such as the ECSgeneralCommand itself. Then it could close itself and spawn the correct window.
Or, possibly a much better solution, if applicable for your application: Use a single main window, with a QStackedWidget that switches widgets when a button is pressed. That's what's typically done.

How to add buttons to a main window in Qt?

I'm new to qt programming so please don't mind if you find it a noob question. I've added a button to my main window but when I run the code the button is not displayed. Here's my code:
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtWidgets>
MainWindow::MainWindow(QWidget *parent)
{
QPushButton *train_button = new QPushButton(this);
train_button->setText(tr("something"));
train_button->move(600, 600);
train_button->show();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
MainWindow::~MainWindow()
{
delete ui;
}
What should I do?
In main window you should use central widget . You have two choices :
Set the button for central widget ( Not so good choice ) :
QPushButton *train_button = new QPushButton(this);
train_button->setText(tr("something"));
setCentralWidget(train_button);
Add a widget and add the button to that widget and set the widget for centralWidget :
QWidget * wdg = new QWidget(this);
QPushButton *train_button = new QPushButton(wdg);
train_button->setText(tr("something"));
setCentralWidget(wdg);
And surely you can use Layouts for your centralWidget:
QWidget * wdg = new QWidget(this);
QVBoxLayout *vlay = new QVBoxLayout(wdg);
QPushButton *btn1 = new QPushButton("btn1");
vlay->addWidget(btn1);
QPushButton *btn2 = new QPushButton("btn2");
vlay->addWidget(btn2);
QPushButton *btn3 = new QPushButton("btn3");
vlay->addWidget(btn3);
wdg->setLayout(vlay);
setCentralWidget(wdg);

Adding drop down menu to Qt GUI - error 'menubar' no declared

I'm trying to create a menu in Qt following this example http://doc.qt.nokia.com/latest/mainwindows-menus.html
but I keep getting the error 'menuBar' not declared in this scope
void Window::createMenus()
{
saveMenu = menuBar()->addMenu("&Save");
}
In context:
#include <QtGui>
#include "borderlayout.h"
#include "window.h"
Window::Window()
{
QTextBrowser *centralWidget = new QTextBrowser;
//***Change this to whatever widget(s) the drawing area is. QPainter or something?
centralWidget->setPlainText(tr("DRAW HERE YAY"));
BorderLayout *layout = new BorderLayout;
layout->addWidget(centralWidget, BorderLayout::Center);
layout->addWidget(createLabel("File ..."), BorderLayout::North);
layout->addWidget(createLabel("Toolbar yo!"), BorderLayout::West);
//layout->addWidget(createLabel("Status bar"), BorderLayout::South);
//Maybe we could put in a status bar. For now let's not worry about it. It's not a requirement.
setLayout(layout);
createMenus();
setWindowTitle(tr("Border Layout"));
}
QLabel *Window::createLabel(const QString &text)
{
QLabel *label = new QLabel(text);
label->setFrameStyle(QFrame::Box | QFrame::Raised);
return label;
}
void Window::createMenus()
{
saveMenu = menuBar()->addMenu("&Save");
}
window.h
#ifndef WINDOW_H
#define WINDOW_H
#include <QWidget>
class QLabel;
class QMenu;
class Window : public QWidget
{
Q_OBJECT
public:
Window();
private:
void createMenus();
QLabel *createLabel(const QString &text);
QMenu *saveMenu();
};
#endif
window.cpp
#include <QtGui>
#include "borderlayout.h"
#include "window.h"
Window::Window()
{
QTextBrowser *centralWidget = new QTextBrowser;
//***Change this to whatever widget(s) the drawing area is. QPainter or something?
centralWidget->setPlainText(tr("DRAW HERE YAY"));
BorderLayout *layout = new BorderLayout;
layout->addWidget(centralWidget, BorderLayout::Center);
layout->addWidget(createLabel("File ..."), BorderLayout::North);
layout->addWidget(createLabel("Toolbar yo!"), BorderLayout::West);
//layout->addWidget(createLabel("Status bar"), BorderLayout::South);
//Maybe we could put in a status bar. For now let's not worry about it. It's not a requirement.
setLayout(layout);
createMenus();
setWindowTitle(tr("Border Layout"));
}
QLabel *Window::createLabel(const QString &text)
{
QLabel *label = new QLabel(text);
label->setFrameStyle(QFrame::Box | QFrame::Raised);
return label;
}
void Window::createMenus()
{
saveMenu = menuBar()->addMenu("&Save");
}
The menu bar is a feature of the QMainWindow class.
Because your Window class is being inherited directly from QWidget, it does not have the menuBar method, hence your error.
You need to subclass your Window class from QMainWindow rather than QWidget.

Resources