Unable to understand how the QScrollArea/QVboxLayout stuff works - c++

I am trying to align vertically some custom widgets into a scrolledArea. Some research lead me to make a QVboxLayout, adding a QScrollArea into it.
I tried and i didn't manage to do it in a proper way.
I found that some people use a two QVboxLayout and Widget level, for example on those pages :
http://www.linuxforums.org/forum/programming-scripting/155452-solved-using-qt-scroll-area.html
http://kunalmaemo.blogspot.fr/2010/07/scrolling-in-custom-widget-using.html
I don't understand why but i tried also.
I read also this and tried, but still doesn't work :
QScrollArea missing Scrollbar.
I must do something wrong but i can't tell what. Sometimes my widgets are not scrolled and are just flattened, sometimes the widget doesn't appear at all but never succeed to show a single scroll area. Here is my current code version(simplified with which i think is sufficient) :
MainWIndowImp.h
class MainWindowImp : public QMainWindow, public Ui_MainWindow
{
Q_OBJECT
public :
MainWindowImp() ;
~MainWindowImp() ;
//more
public slots :
//some stuff
private
std::vector<SliderFloat*> _sliders ; //custom widget, works fine
}
ui_mainwindow.h
class Ui_MainWindow
{
public:
QWidget *centralwidget;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
centralwidget = new QWidget(MainWindow);
_slider_GB = new QGroupBox(centralwidget);
_slider_GB->setObjectName(QString::fromUtf8("_slider_GB"));
_slider_GB->setGeometry(QRect(630, 10, 351, 351));
_mainScrollArea = new QScrollArea(_slider_GB);
_mainScrollArea->setObjectName(QString::fromUtf8("_mainScrollArea"));
_mainScrollArea->setGeometry(QRect(10, 40, 331, 301));
_mainScrollArea->setWidgetResizable(true);
scrollAreaWidgetContents = new QWidget();
scrollAreaWidgetContents->setObjectName(QString::fromUtf8("scrollAreaWidgetContents"));
scrollAreaWidgetContents->setGeometry(QRect(0, 0, 329, 299));
_mainScrollArea->setWidget(scrollAreaWidgetContents);
}
}
MainWindowImp.cpp
MainWindowImp::MainWindowImp()
{
setupUi(this)
}
void MainWindowImp::updateSliders()
{
QVBoxLayout *mainLayout = new QVBoxLayout(this) ;
mainLayout->addWidget(_mainScrollArea);
QWidget *contents = new QWidget ;
QVBoxLayout *layout = new QVBoxLayout(contents) ;
for(uint32_t i=0;i<_approx->latentVariables().cols();++i)
{
layout->addWidget(_sliders[i]) ;
}
layout->setSizeConstraint(QLayout::SetMinimumSize);
_mainScrollArea->setWidget(contents);
}
Notes that i used QtDesigner for the GUI, and i just set into it the QScrollArea _mainScrollArea, and it automatically set a QWidget scrollAreaWidgetContents and set it to the QScrollArea. Maybe my issues come from it ?
Thank you for the replies
EDIT :
here is the mainwindow.ui file (removed a lot of things that aren' relevant) :
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1002</width>
<height>524</height>
</rect>
</property>
<property name="windowTitle">
<string>Main Window</string>
</property>
<widget class="QWidget" name="centralwidget">
<property name="minimumSize">
<size>
<width>981</width>
<height>0</height>
</size>
</property>
<widget class="MyGLViewer" name="_qglv" native="true">
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>600</width>
<height>400</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>125</width>
<height>100</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>800</width>
<height>600</height>
</size>
</property>
<property name="mouseTracking">
<bool>false</bool>
</property>
</widget>
<widget class="QGroupBox" name="_slider_GB">
<property name="geometry">
<rect>
<x>630</x>
<y>10</y>
<width>351</width>
<height>351</height>
</rect>
</property>
<property name="title">
<string>Coordinates</string>
</property>
<widget class="QScrollArea" name="_mainScrollArea">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>331</width>
<height>301</height>
</rect>
</property>
<property name="widgetResizable">
<bool>true</bool>
</property>
<widget class="QWidget" name="scrollAreaWidgetContents">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>329</width>
<height>299</height>
</rect>
</property>
</widget>
</widget>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1002</width>
<height>29</height>
</rect>
</property>
</widget>
</widget>
<customwidgets>
<customwidget>
<class>MyGLViewer</class>
<extends>QWidget</extends>
<header>myglviewer.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

Related

Make a Character Counter for a QLineEdit

I am trying to make a simple character counter, like the one in twitter, in QT specifically with the QLineEdit feature. Ideally, it should record the number of characters entered in a QLineEdit and display the number recorded in a separate display label. For example, spotify has a character counter when naming and adding a description to a playlist.
The function that I have declared to count the number of characters entered in the QLineEdit is defined like so:
void MainWindow::countChar()
{
QString tempString = ui->displayLabel->text(); //temp variable to hold the lineEdit's text
int output = tempString.size(); //to get the number of characters in the lineEdit
QString s = QString::number(output);//convert an int to QString
ui->CharCounter->setText(s); //display the number in the displayLabel(CharCounter)
ui->CharCounter->adjustSize();
}
I call this function in my main.cpp under the object, w.
w.countChar();
The reason I want to create a character counter function is because I have set a character limit for the QLineEdit so whatever the user enters can be filled into the main displayLabel at the minimum size of the window. I have done that by writing another function:
void MainWindow::setlineInputTextCharLimit(int limit)
{
ui->inputText->setMaxLength(limit);
}
Which I called under the same object, w:
w.setLineInputTextCharLimit(200);
QTCreator is able to successfully build but the charCounter displayLabel does not change in value after I enter some amount of text into the QLineEdit.
image of the application built
It is clear that the displayLabel for the character counter is being read and has been activated however when I enter any amount of text, the value does not change.
The result after there is some text entered into the QLineEdit
So if the displayLabel is registered and a value is being shown, the function should be working but there is definitely something wrong with it too because the value not change to anything from that '0'?.
Edit: the UI file:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>554</width>
<height>463</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>80</x>
<y>20</y>
<width>311</width>
<height>211</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="inputText"/>
</item>
<item>
<widget class="QPushButton" name="textBtn">
<property name="text">
<string>Display Text</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="displayLabel">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>100</width>
<height>100</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="CharCounter">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>554</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
And heres the signal-slot connection:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->textBtn, &QPushButton::clicked, this, &MainWindow::setText);
connect(ui->inputText, &QLineEdit::textChanged, this, &MainWindow::countChar);
}
If you want to count the texts you must count each time the text changes and for that you must use the textChanged() signal, in the following code I show an example:
#include <QApplication>
#include <QLabel>
#include <QLineEdit>
#include <QVBoxLayout>
#include <QWidget>
class CounterWidget: public QWidget
{
Q_OBJECT
Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
Q_PROPERTY(int maxLenght READ maxLenght WRITE setMaxLenght)
Q_PROPERTY(int length READ length)
public:
CounterWidget(QWidget *parent=nullptr):
CounterWidget(200, parent)
{
}
CounterWidget(int maxLength, QWidget *parent=nullptr):
QWidget(parent),
layout(this)
{
layout.addWidget(&lineEdit);
layout.addWidget(&counterLabel, 0, Qt::AlignTop | Qt::AlignRight);
connect(&lineEdit, &QLineEdit::textChanged, this, &CounterWidget::countChar);
connect(&lineEdit, &QLineEdit::textChanged, this, &CounterWidget::textChanged);
lineEdit.setMaxLength(maxLength);
countChar("");
}
QString text() const{
return lineEdit.text();
}
void setText(const QString &text){
lineEdit.setText(text);
}
int maxLenght() const{
return lineEdit.maxLength();
}
void setMaxLenght(int maxLenght){
lineEdit.setMaxLength(maxLenght);
}
int length() const{
return lineEdit.text().size();
}
signals:
void textChanged(const QString & text);
private slots:
void countChar(const QString & text){
QString text_label = QString("%1/%2").arg(text.size()).arg(lineEdit.maxLength());
counterLabel.setText(text_label);
}
private:
QVBoxLayout layout;
QLineEdit lineEdit;
QLabel counterLabel;
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
CounterWidget w;
w.show();
return a.exec();
}
#include "main.moc"
I was reading the text from QLabel and not QLineEdit. So the part in my code:
QString tempString = ui->displayLabel->text();
was only reading the text from the label when I wanted to read the text entered in the QLineEdit. So I changed the code to:
QString tempString = ui->inputText->text();
and that fixed the problem.
Thanks #FrozenM and #eyllanesc

How to update a window in QT?

Im working on a simple project in QtCreator where you input text into a line_edit which then gets printed after clicking a button. It works but I need to resize the window in order to see the updated/changed display.
So starting off with the main.cpp, I have left it as default after some tests:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
That has the issue I was talking about above. I decided to add w.update(); and see if that fixed the issue, it did not. I thought maybe it was because the program was not looping, so I entered the code in a while(true) loop which also was to no avail.
The mainwindow.cpp file is as follows:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->textBtn, SIGNAL(clicked(bool)), this, SLOT(setText()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setText()
{
QString temp = ui->inputText->text();
ui->displayLabel->setText(temp);
}
MainWindow.hpp:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void setText();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Is there a QObject or predifined function in QT that allows me to update the window or automatically updates the window after a detected user change?
Edit: The UI file might be of importance as well:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>554</width>
<height>463</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QLabel" name="displayLabel">
<property name="geometry">
<rect>
<x>140</x>
<y>150</y>
<width>251</width>
<height>91</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="scaledContents">
<bool>true</bool>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>130</x>
<y>30</y>
<width>251</width>
<height>81</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="inputText"/>
</item>
<item>
<widget class="QPushButton" name="textBtn">
<property name="text">
<string>Display Text</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>554</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QToolBar" name="mainToolBar">
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
<widget class="QStatusBar" name="statusBar"/>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
The problem is not the update of the GUI but the QLabel does not change size, the initial size depends on the initial text, and if you set a text with larger size only part of the text will be displayed. To adjust the size of the label to the size of the text you must use adjustSize():
void MainWindow::setText()
{
QString temp = ui->inputText->text();
ui->displayLabel->setText(temp);
ui->displayLabel->adjustSize();
}
On the other hand in Qt5 it is advisable to use the new connection syntax since they have several advantages as indicated by the docs, in your case you must change your code to:
connect(ui->textBtn, &QPushButton::clicked, this, &MainWindow::setText);

Qt C++ QLabel Clickable mouse events doesn't work

I have a big doubt and problem. After try a lot of tutorials and examples, I cannot receive signal clicks in my QLabel. If I do the same, but in a QDialog (not in a QLabel), I can know the status of the mouse.
I paste my example code, before that, I present my steps to make the project:
I make a project, make a QMainWindow (named testWindow, maked graphically), after that, I add a QLabel (lblMouse), I mark the mouseTracking property as true. After execute, my QLabel lblMouse doesn't react to my mouse events.
Another doubt is: after execute my program, the text of my QLabel is not "Hello" as I assign in his constructor, it will be executed after ui is executed? I can change it from the constructor of the ui with ui->lblMouse->setText("Hello"); (Probably I have an error, I'm a C programmer and I'm trying to enter in the C++ world)
After that, I edit the code (testWindow.cpp and testWindow.h):
Here is my cpp code:
testWindow::testWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::testWindow)
{
ui->setupUi(this);
//It will not be neccesary because I mark on the checkbox of mouseTracking
ui->lblMouse->setMouseTracking(true);
connect(ui->lblMouse, SIGNAL(Mouse_Pos()), this, SLOT(Mouse_current_pos()));
connect(ui->lblMouse, SIGNAL(Mouse_Pressed()), this, SLOT(Mouse_Pressed()));
connect(ui->lblMouse, SIGNAL(Mouse_Left()), this, SLOT(Mouse_left()));
}
testWindow::~testWindow()
{
delete ui;
}
void testWindow::Mouse_current_pos()
{
ui->lblMouse_Current_Pos->setText(QString("X = aa, Y = aa")/*.arg(ui->lblMouse->x())*/);
}
void testWindow::Mouse_Pressed()
{
ui->lblMouse_Current_Pos->setText(QString("X = aa, Y = aa")/*.arg(ui->lblMouse->x())*/);
}
void testWindow::Mouse_left()
{
ui->lblMouse_Current_Pos->setText(QString("X = aa, Y = aa")/*.arg(ui->lblMouse->x())*/);
}
lblMouse::lblMouse(QWidget *parent): QLabel(parent)
{
// strange for me, the initial text of the label is not Hello
this->setText("Hello");
}
lblMouse::~lblMouse()
{
}
void lblMouse::mouseMoveEvent(QMouseEvent *ev)
{
this->xpos = ev->x();
this->ypos = ev->y();
emit Mouse_Pos();
}
void lblMouse::mousePressEvent(QMouseEvent *)
{
emit Mouse_Pressed();
// ev->x();
}
void lblMouse::leaveEvent(QEvent *)
{
emit Mouse_Left();
}
Here is my h file:
#ifndef TESTWINDOW_H
#define TESTWINDOW_H
#include <QMainWindow>
#include <QLabel>
#include <QMouseEvent>
#include <QEvent>
#include <QDebug>
namespace Ui {
class testWindow;
class lblMouse;
}
class lblMouse : public QLabel
{
Q_OBJECT
public:
explicit lblMouse(QWidget *parent = 0);
~lblMouse();
int xpos,ypos;
void leaveEvent(QEvent *);
protected:
void mouseMoveEvent(QMouseEvent *ev);
void mousePressEvent(QMouseEvent *ev);
signals:
void Mouse_Pressed();
void Mouse_Pos();
void Mouse_Left();
};
class testWindow : public QMainWindow
{
Q_OBJECT
public:
explicit testWindow(QWidget *parent = 0);
~testWindow();
private:
Ui::testWindow *ui;
private slots:
void Mouse_current_pos();
void Mouse_Pressed();
void Mouse_left();
};
#endif // TESTWINDOW_H
Also, here is my .ui file (thanks #Thomas ):
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>testWindow</class>
<widget class="QMainWindow" name="testWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="lblMouse">
<property name="geometry">
<rect>
<x>20</x>
<y>60</y>
<width>331</width>
<height>241</height>
</rect>
</property>
<property name="mouseTracking">
<bool>true</bool>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string>Mouse Area</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QGroupBox" name="groupBox">
<property name="geometry">
<rect>
<x>400</x>
<y>50</y>
<width>201</width>
<height>191</height>
</rect>
</property>
<property name="title">
<string>Mouse Events</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="lblMouse_Current_Pos">
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="text">
<string>x=0, Y=0</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="lblMouse_Current_Event">
<property name="frameShape">
<enum>QFrame::Panel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>23</height>
</rect>
</property>
<widget class="QMenu" name="menuMenu">
<property name="title">
<string>&Menu</string>
</property>
<addaction name="actionImportar"/>
</widget>
<addaction name="menuMenu"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<action name="actionImportar">
<property name="text">
<string>&Importar...</string>
</property>
</action>
</widget>
<resources/>
<connections/>
</ui>
Edit:
I'm seing a runtime error in the console (is not a compilation error, I got this messages after run the program, but it continues running):
QObject::connect: No such signal QLabel::Mouse_Left() in
../testwindow.cpp:17
QObject::connect: (sender name: 'lblMouse')
QObject::connect: (receiver name: 'testWindow')
PD: I'm not sure if it is the problem. I have tested other ways to do this and I have not good results.
Thanks!
Your label in ui is QLabel class, but you have created lblMouse. So, in ui you must change code
<widget class="QLabel" name="lblMouse">
to
<widget class="lblMouse" name="lblMouse">
EDIT:
To change this you can:
Use any text editor;
Go to Designer in Qt Creator chosing your ui, select your QLabel, call context menu and click "Promote to...". Then check that "Base class name" is correct (QLabel), write your class (lblMouse) in "Promoted class name" field, click "Add" button, then "Promote" button. That's all. Your label now your own label class.
About setText() method.
Go to designer;
Choose your label;
In right side in object propeties find QLabel area and click on a round arrow front of "text" property. That's all. Now, if you do setText() method in constructor - it will works.
You just need to use your lblMouse class.
In .h file, add this in class testWindow
lblMouse *lblMouse_Current_Pos;
In .cpp file, add this in contructor:
lblMouse_Current_Pos = new lblMouse(this);
lblMouse_Current_Pos->setMouseTracking(true);
connect(lblMouse_Current_Pos, SIGNAL(Mouse_Pos()), this, SLOT(Mouse_current_pos()));
connect(lblMouse_Current_Pos, SIGNAL(Mouse_Pressed()), this, SLOT(Mouse_Pressed()));
connect(lblMouse_Current_Pos, SIGNAL(Mouse_Left()), this, SLOT(Mouse_left()));

Qt Get Label To Stay Certain % Off Of Bottom

I am making a math application that will be used by kids to learn basic math skills. So far I have the title label re-sizing, and staying a certain distance from the top, but since Qt's origin is in the top-left, I couldn't line up the bottom start button. Any help of suggestion are greatly appreciated, and thank you!
Here is how far the start label should be off of the bottom:
Here is what happens when I re-size too far widthwize:
Chalkboard.cpp:
#include "chalkboard.h"
#include "ui_chalkboard.h"
Chalkboard::Chalkboard(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Chalkboard)
{
ui->setupUi(this);
//setWindowFlags(Qt::Window | Qt::FramelessWindowHint);
id = QFontDatabase::addApplicationFont(":/fonts/chawp.ttf");
family = QFontDatabase::applicationFontFamilies(id).at(0);
chawp = family;
setFont(chawp);
scene = new QGraphicsScene(100, 100, 100, 100);
ui->graphicsView->setScene(scene);
image = new QImage(":/images/depositphotos_40177799-Seamless-Chalkboard-Texture.jpg");
brush = new QBrush(*image);
ui->graphicsView->setBackgroundBrush(*brush);
titleEffect = new QGraphicsDropShadowEffect();
titleEffect->setBlurRadius(10);
titleEffect->setColor(QColor("#e0dbd1"));
titleEffect->setXOffset(0);
titleEffect->setYOffset(0);
startEffect = new QGraphicsDropShadowEffect();
startEffect->setBlurRadius(10);
startEffect->setColor(QColor("#e0dbd1"));
startEffect->setXOffset(0);
startEffect->setYOffset(0);
ui->labelTitle->setStyleSheet("color: #e0dbd1;font: url(:/font/chawp.ttf);");
ui->labelStart->setStyleSheet("color: #e0dbd1;font: url(:/font/chawp.ttf);");
ui->labelTitle->setGraphicsEffect(titleEffect);
ui->labelStart->setGraphicsEffect(startEffect);
}
Chalkboard::~Chalkboard()
{
delete ui;
}
void Chalkboard::resizeEvent(QResizeEvent *event)
{
QFontMetrics temp(chawp);
if (windowState() != Qt::WindowFullScreen)
{
setMaximumSize(1920, 1080);
}
QFont temp1(chawp);
QFont temp2(chawp);
temp1.setPixelSize(width()/10);
temp2.setPixelSize(width()/15);
ui->graphicsView->move(0, 0);
ui->graphicsView->resize(width(), height());
ui->labelTitle->resize(width(), height());
ui->labelTitle->move(0, 15);
ui->labelTitle->setFont(temp1);
//My failed attempt at it:
if (height()/5 < 75)
{
ui->labelStart->resize(width(), height());
ui->labelStart->move(0, height() - (height() / 5));
ui->labelStart->setFont(temp2);
}
}
Main.cpp:
#include "chalkboard.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Chalkboard w;
w.show();
return a.exec();
}
Chalkboard.h:
#ifndef CHALKBOARD_H
#define CHALKBOARD_H
#include <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QFontDatabase>
#include <QDebug>
#include <QGraphicsDropShadowEffect>
namespace Ui {
class Chalkboard;
}
class Chalkboard : public QMainWindow
{
Q_OBJECT
public:
explicit Chalkboard(QWidget *parent = 0);
~Chalkboard();
public slots:
void resizeEvent(QResizeEvent* event);
private:
QGraphicsDropShadowEffect * titleEffect;
QGraphicsDropShadowEffect * startEffect;
QFont chawp;
QGraphicsScene *scene;
QString family;
int id;
QImage *image;
QBrush *brush;
Ui::Chalkboard *ui;
};
#endif // CHALKBOARD_H
Chalkboard.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Chalkboard</class>
<widget class="QMainWindow" name="Chalkboard">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>644</width>
<height>468</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>644</width>
<height>468</height>
</size>
</property>
<property name="windowTitle">
<string>Chalkboard</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QGraphicsView" name="graphicsView">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>61</width>
<height>71</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="labelStart">
<property name="geometry">
<rect>
<x>120</x>
<y>290</y>
<width>311</width>
<height>131</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>35</pointsize>
</font>
</property>
<property name="text">
<string>Start</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
<widget class="QLabel" name="labelTitle">
<property name="geometry">
<rect>
<x>100</x>
<y>50</y>
<width>391</width>
<height>151</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>50</pointsize>
</font>
</property>
<property name="text">
<string>Chalkboard</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>40</x>
<y>220</y>
<width>131</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="resource.qrc">
<normaloff>:/images/liberty-technology-arrow-1.png</normaloff>:/images/liberty-technology-arrow-1.png</iconset>
</property>
</widget>
<widget class="QPushButton" name="pushButton_2">
<property name="geometry">
<rect>
<x>444</x>
<y>200</y>
<width>111</width>
<height>61</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="resource.qrc">
<normaloff>:/images/liberty-technology-arrow-2.png</normaloff>:/images/liberty-technology-arrow-2.png</iconset>
</property>
</widget>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="resource.qrc"/>
</resources>
<connections/>
</ui>
I finally solved this by simply setting the QLabel's Y-Axis to (height()-(ui->pushButtonStart->height()))
Another solution:
Create a QFrame widget and put your labels and buttons inside, together with the necessary layouts and spacers.
In your resize event handler just set the proper width and height for this frame like you do for QGraphicsView (to occupy whole parent widget area).
I have modified your .ui file as a hint:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Chalkboard</class>
<widget class="QMainWindow" name="Chalkboard">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>644</width>
<height>468</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>644</width>
<height>468</height>
</size>
</property>
<property name="windowTitle">
<string>Chalkboard</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QGraphicsView" name="graphicsView">
<property name="geometry">
<rect>
<x>20</x>
<y>20</y>
<width>311</width>
<height>341</height>
</rect>
</property>
</widget>
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>210</x>
<y>10</y>
<width>349</width>
<height>401</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLabel" name="labelTitle">
<property name="font">
<font>
<pointsize>50</pointsize>
</font>
</property>
<property name="text">
<string>Chalkboard</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/images/liberty-technology-arrow-1.png</normaloff>:/images/liberty-technology-arrow-1.png</iconset>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset>
<normaloff>:/images/liberty-technology-arrow-2.png</normaloff>:/images/liberty-technology-arrow-2.png</iconset>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QLabel" name="labelStart">
<property name="font">
<font>
<pointsize>35</pointsize>
</font>
</property>
<property name="text">
<string>Start</string>
</property>
<property name="alignment">
<set>Qt::AlignHCenter|Qt::AlignTop</set>
</property>
</widget>
</item>
</layout>
</widget>
<zorder>graphicsView</zorder>
<zorder>frame</zorder>
<zorder>labelTitle</zorder>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
<include location="resource.qrc"/>
</resources>
<connections/>
</ui>

Open second window in Qt

I am trying to compile my code written in C++, using Qt Creator. I am trying to create second window which will appear after click to menu item in main window and this window should have separate .ui file. But during compilation I get this error:
/home/martin/Code/C++/Map_generator/map_generator/preferenceswindow.cpp:4: error: prototype for 'Ui::PreferencesWindow::PreferencesWindow(QWidget*)' does not match any in class 'Ui::PreferencesWindow'
Ui::PreferencesWindow::PreferencesWindow(QWidget *parent)
^
/home/bo/Code/C++/Map_generator/build-map_generator-Desktop-Debug/ui_preferenceswindow.h:88: error: candidates are: constexpr Ui::PreferencesWindow::PreferencesWindow(Ui::PreferencesWindow&&)
class PreferencesWindow: public Ui_PreferencesWindow {};
^
What could be wrong?
preferenceswindow.h
#ifndef PREFERENCESWINDOW_H
#define PREFERENCESWINDOW_H
#include <QWidget>
namespace Ui
{
class PreferencesWindow;
}
class PreferencesWindow : public QWidget
{
Q_OBJECT
public:
explicit PreferencesWindow(QWidget *parent = 0);
signals:
//public Q_SLOTS:
private:
PreferencesWindow *uip;
};
#endif // PREFERENCESWINDOW_H
preferenceswindow.cpp
#include "preferenceswindow.h"
#include "ui_preferenceswindow.h"
Ui::PreferencesWindow::PreferencesWindow(QWidget *parent)
:QWidget(parent), uip(new Ui::PreferencesWindow)
{
uip->setupUi(this);
}
preferenceswindow.ui file
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PreferencesWindow</class>
<widget class="QWidget" name="PreferencesWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>326</width>
<height>159</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>200</x>
<y>100</y>
<width>99</width>
<height>27</height>
</rect>
</property>
<property name="text">
<string>Save</string>
</property>
</widget>
<widget class="QSpinBox" name="spinBox">
<property name="geometry">
<rect>
<x>90</x>
<y>100</y>
<width>81</width>
<height>27</height>
</rect>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="value">
<number>15</number>
</property>
</widget>
<widget class="QSpinBox" name="spinBox_2">
<property name="geometry">
<rect>
<x>90</x>
<y>20</y>
<width>81</width>
<height>27</height>
</rect>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>100</number>
</property>
</widget>
<widget class="QSpinBox" name="spinBox_3">
<property name="geometry">
<rect>
<x>90</x>
<y>60</y>
<width>81</width>
<height>27</height>
</rect>
</property>
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>1000</number>
</property>
<property name="value">
<number>60</number>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>20</x>
<y>30</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Columns</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>20</x>
<y>70</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Rows</string>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>20</x>
<y>110</y>
<width>67</width>
<height>17</height>
</rect>
</property>
<property name="text">
<string>Grid Size</string>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
Your uip variable is declared as PreferencesWindow, when you want it to be declared as Ui::PreferencesWindow:
private:
PreferencesWindow *uip;
change it to
private:
Ui::PreferencesWindow *uip;
You are also defining a Ui::PreferencesWindow constructor in preferenceswindow.cpp. This is not what you want to do. You want to define PreferencesWindow constructor there. Like this:
PreferencesWindow::PreferencesWindow(QWidget *parent)
:QWidget(parent), uip(new Ui::PreferencesWindow)
{
uip->setupUi(this);
}