Qt with C++: class "AddDialog" has no member "carNameEdit" - c++

i am following this tutorial from Qt to create my first porject. I have renamed some Widgets, but I am then consistently using my own names.
But when I now try to acces the text of a label in AddDialog, AddDialog doesn´t seem to have that Label, even tough the names are the same and I have it like in the tutorial.
Here is the code:
carrental.cpp
#include "carrental.h"
#include "stdafx.h"
#include "adddialog.h"
#include "ui_adddialog.h"
CarRental::CarRental(QWidget* parent)
: QWidget(parent)
{
ui.setupUi(this);
}
void CarRental::on_addButton_clicked()
{
AddDialog dialog(this);
if (dialog.exec()) {
QString carName = dialog.carNameEdit->text();
QString carModel = dialog.carModelEdit->text();
if (!carName.isEmpty() && !carModel.isEmpty()) {
QListWidgetItem* item = new QListWidgetItem(carName, ui.carList);
item->setData(Qt::UserRole, carModel);
ui.carList->setCurrentItem(item);
}
}
}
adddialog.h:
#pragma once
#include <QDialog>
#include "ui_adddialog.h"
class AddDialog : public QDialog
{
Q_OBJECT
public:
AddDialog(QWidget* parent = Q_NULLPTR);
private:
Ui::AddDialog ui;
};
adddialog.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>AddDialog</class>
<widget class="QDialog" name="AddDialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>345</width>
<height>230</height>
</rect>
</property>
<property name="windowTitle">
<string>AddDialog</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>60</x>
<y>50</y>
<width>221</width>
<height>131</height>
</rect>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QGridLayout" name="inputLayout">
<item row="0" column="0">
<widget class="QLabel" name="carNameText">
<property name="text">
<string>Car Name:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="nameEdit">
<property name="text">
<string>Name</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="carModelText">
<property name="text">
<string>Car Model:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="carModelEdit"/>
</item>
</layout>
</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>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout" name="okLayout">
<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="okButton">
<property name="text">
<string>OK</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections>
<connection>
<sender>okButton</sender>
<signal>clicked()</signal>
<receiver>AddDialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>251</x>
<y>167</y>
</hint>
<hint type="destinationlabel">
<x>100</x>
<y>196</y>
</hint>
</hints>
</connection>
</connections>
</ui>
Thanks

carNameEdit and carModelEdit are attributes of the private ui object so you cannot access them, a possible solution is to make them public but another better option is to create public methods that expose the strings:
public:
AddDialog(QWidget* parent = Q_NULLPTR);
QString carName() const;
QString carModel() const;
private:
Ui::AddDialog ui;
QString AddDialog::carName() const
{
return ui.carNameEdit->text();
}
QString AddDialog::carModel() const
{
return ui.carModelEdit->text();
}
Then change to:
QString carName = dialog.carName();
QString carModel = dialog.carModel();

Small addition to good answer from #eyllanesc; You can use QObject::findChild Qt feature:
In your case it might be:
QLineEdit *carModelEdit= dialog.findChild<QLineEdit*>("carModelEdit");
qDebug() << carModelEdit->text();
It works, because after ui.setupUi(this); all elements of your UI become children of your widget.
Quite useful for unit testing, but whether you should use it in your production code is a bit questionable.

Related

QTableView row height animation

In a form, I have 2 instances of QTableView (tableView1 & tableView2) using the same model. The goal is to link items together:
In the first table view, select the object you want to define as the parent.
In the second table view, add a tick mark on the object(s) you want to define as the child. An object cannot be its own parent (it can have no parent).
The way I wanted to proceed is by hiding in tableView2 the object selected in tableView1, and to be precise, by setting the row height to 0 with an animation.
That very part works but problems start to arise when I try to implement the creation/deletion of new objects (rows get inserted or removed) or with fast change of selection with the keyboard.
Inserting a new row makes any row under it reappear if it was hidden.
Deleting the row that was selected in tableView1 makes the next row be automatically selected, with no effect on tableView2.
Selecting rows faster than the animation can handle sometimes leaves row with a different height than normal.
I strongly suspect this behavior is caused by how the selection model needs to react to new rows inserted above the selection and how in contrary, it does not need to react to the current row being deleted (the next row takes the position of the deleted one and appears to be selected instead).
Even with that in mind, I cannot get my head around it; I have tried adding more signal/slot connections (on rowsAboutToBeInserted/rowsAboutToBeRemoved) to no avail.
Below is the code I have so far.
Note: I created the sample on QtCreator because it is quicker but for some reason, the animation is extremely crappy; my actual longer code is on Visual Studio, which makes it smooth. Either some optimization is missing or using QTableWidget makes it slower than my actual code with separate QTableView and subclass of QAbstractItemModel.
Even if the animation is bad, the only way in that code for rows visible in tableView1 to appear/reappear in tableView2 is the animations.
MainWindow.h
#pragma once
#include <QtWidgets/QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
public slots:
void onPrependClicked();
void onInsertClicked();
void onAppendClicked();
void onDeleteClicked();
private:
Ui::MainWindow *ui;
};
MainWindow.cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QtCore/QParallelAnimationGroup>
#include <QtCore/QVariantAnimation>
#include <QtWidgets/QStyledItemDelegate>
#include <QtWidgets/QWidget>
class RowAnimator : public QVariantAnimation {
public:
RowAnimator(QObject* parent) : QVariantAnimation(parent), Row(-1) { setDuration(500); /* for the investigation, we keep a large value to make it possible to see it */ }
int Row;
};
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//ui->tableView1 and ui->tableView2 will share the same model().
//ui->tableView1 is set to select a single row at any one time.
auto model = ui->tableView1->model();
ui->tableView2->setModel(model);
RowAnimator* hideRowAnimator = new RowAnimator(ui->tableView2),
* showRowAnimator = new RowAnimator(ui->tableView2);
{ //Setup the RowAnimator
int rowHeight = ui->tableView2->rowHeight(0);
hideRowAnimator->setStartValue(rowHeight); hideRowAnimator->setEndValue(0);
showRowAnimator->setStartValue(0); showRowAnimator->setEndValue(rowHeight);
QObject::connect(hideRowAnimator, &QVariantAnimation::valueChanged, [=](const QVariant& value) {
if (hideRowAnimator->Row >= 0)
ui->tableView2->setRowHeight(hideRowAnimator->Row, value.toInt());
});
QObject::connect(showRowAnimator, &QVariantAnimation::valueChanged, [=](const QVariant& value) {
if (showRowAnimator->Row >= 0)
ui->tableView2->setRowHeight(showRowAnimator->Row, value.toInt());
});
//Update the RowAnimator when rows are inserted or removed
QObject::connect(model, &QAbstractItemModel::rowsAboutToBeInserted, hideRowAnimator, [hideRowAnimator](const QModelIndex&, int first, int last) {
if (first <= hideRowAnimator->Row)
hideRowAnimator->Row += (1 + last - first);
}, Qt::DirectConnection);
QObject::connect(model, &QAbstractItemModel::rowsAboutToBeInserted, showRowAnimator, [showRowAnimator](const QModelIndex&, int first, int last) {
if (first <= showRowAnimator->Row)
showRowAnimator->Row += (1 + last - first);
}, Qt::DirectConnection);
QObject::connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, hideRowAnimator, [hideRowAnimator](const QModelIndex&, int first, int last) {
if (last < hideRowAnimator->Row)
hideRowAnimator->Row -= (1 + last - first);
else if (first <= hideRowAnimator->Row)
hideRowAnimator->Row = -1;
}, Qt::DirectConnection);
QObject::connect(model, &QAbstractItemModel::rowsAboutToBeRemoved, showRowAnimator, [showRowAnimator](const QModelIndex&, int first, int last) {
if (last < showRowAnimator->Row)
showRowAnimator->Row -= (1 + last - first);
else if (first <= showRowAnimator->Row)
showRowAnimator->Row = -1;
}, Qt::DirectConnection);
}
QParallelAnimationGroup* parallelAnimation = new QParallelAnimationGroup(ui->tableView2);
parallelAnimation->addAnimation(hideRowAnimator);
parallelAnimation->addAnimation(showRowAnimator);
//Setup the events to animate.
//When a row gets selected in tableView1 -> hide the corresponding row in tableView2 + show the previously hiidden row.
QObject::connect(ui->tableView1->selectionModel(), &QItemSelectionModel::selectionChanged, parallelAnimation,
[hideRowAnimator, showRowAnimator, parallelAnimation](const QItemSelection& selected) {
if (selected.isEmpty() || selected.indexes().isEmpty()) {
showRowAnimator->Row = hideRowAnimator->Row;
hideRowAnimator->Row = -1;
}
else if (QModelIndex selectedIndex = selected.indexes().first(); selectedIndex.isValid()) {
showRowAnimator->Row = hideRowAnimator->Row;
hideRowAnimator->Row = selectedIndex.row();
}
else {
showRowAnimator->Row = hideRowAnimator->Row;
hideRowAnimator->Row = -1;
}
parallelAnimation->start();
}
);
}
void MainWindow::onPrependClicked()
{
auto model = ui->tableView1->model();
model->insertRow(0, QModelIndex());
// This makes the hidden row reappear
}
void MainWindow::onInsertClicked()
{
auto model = ui->tableView1->model();
model->insertRow(1, QModelIndex());
// This makes the hidden row reappear except if it was row 0 (only rows under the inserted one reappear).
}
void MainWindow::onAppendClicked()
{
auto model = ui->tableView1->model();
model->insertRow(model->rowCount(), QModelIndex());
// Apparently no animation (there is no row are under that new one).
}
void MainWindow::onDeleteClicked()
{
auto selectionModel = ui->tableView1->selectionModel();
if (selectionModel->currentIndex().isValid()) {
auto model = ui->tableView1->model();
model->removeRow(selectionModel->currentIndex().row());
}
//This triggers an animation on the row right under the one being deleted.
//At the end, that row is shown (showRowAnimator is evaluated last) even though deleting a row apparently changes the selection.
//The correct behavior is either to have nothing selected or have the newly selected row hidden in tableView2.
}
MainWindow.ui
<?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>800</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QTableWidget" name="tableView1">
<property name="mouseTracking">
<bool>false</bool>
</property>
<property name="focusPolicy">
<enum>Qt::WheelFocus</enum>
</property>
<property name="styleSheet">
<string notr="true">QTableView { outline:none; }
QTableView::item:selected { background:#0078D7; }</string>
</property>
<property name="locale">
<locale language="English" country="UnitedStates"/>
</property>
<property name="inputMethodHints">
<set>Qt::ImhLatinOnly</set>
</property>
<property name="autoScroll">
<bool>false</bool>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="tabKeyNavigation">
<bool>false</bool>
</property>
<property name="showDropIndicator" stdset="0">
<bool>false</bool>
</property>
<property name="dragDropOverwriteMode">
<bool>false</bool>
</property>
<property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum>
</property>
<property name="showGrid">
<bool>false</bool>
</property>
<property name="gridStyle">
<enum>Qt::NoPen</enum>
</property>
<property name="wordWrap">
<bool>false</bool>
</property>
<property name="cornerButtonEnabled">
<bool>false</bool>
</property>
<attribute name="horizontalHeaderVisible">
<bool>true</bool>
</attribute>
<attribute name="verticalHeaderVisible">
<bool>true</bool>
</attribute>
<row>
<property name="text">
<string>1</string>
</property>
</row>
<row>
<property name="text">
<string>2</string>
</property>
</row>
<row>
<property name="text">
<string>3</string>
</property>
</row>
<column>
<property name="text">
<string>1</string>
</property>
</column>
<column>
<property name="text">
<string>2</string>
</property>
</column>
<item row="0" column="0">
<property name="text">
<string>Item 1,1</string>
</property>
</item>
<item row="0" column="1">
<property name="text">
<string>Item 1,2</string>
</property>
</item>
<item row="1" column="0">
<property name="text">
<string>Item 2,1</string>
</property>
</item>
<item row="1" column="1">
<property name="text">
<string>Item 2,2</string>
</property>
</item>
<item row="2" column="0">
<property name="text">
<string>Item 3,1</string>
</property>
</item>
<item row="2" column="1">
<property name="text">
<string>Item 3,2</string>
</property>
</item>
</widget>
</item>
<item row="1" column="0">
<widget class="QPushButton" name="appendButton">
<property name="text">
<string>Append</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QTableView" name="tableView2"/>
</item>
<item row="2" column="0">
<widget class="QPushButton" name="insertButton">
<property name="text">
<string>Insert</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="prependButton">
<property name="text">
<string>Prepend</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QPushButton" name="deleteButton">
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>800</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections>
<connection>
<sender>appendButton</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>onAppendClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>202</x>
<y>530</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>insertButton</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>onInsertClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>202</x>
<y>559</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>prependButton</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>onPrependClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>596</x>
<y>530</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
<connection>
<sender>deleteButton</sender>
<signal>clicked()</signal>
<receiver>MainWindow</receiver>
<slot>onDeleteClicked()</slot>
<hints>
<hint type="sourcelabel">
<x>596</x>
<y>559</y>
</hint>
<hint type="destinationlabel">
<x>399</x>
<y>299</y>
</hint>
</hints>
</connection>
</connections>
<slots>
<slot>onAppendClicked()</slot>
<slot>onInsertClicked()</slot>
<slot>onPrependClicked()</slot>
<slot>onDeleteClicked()</slot>
</slots>
</ui>

Wrong returned position value

I'm trying to link pushbuttons using a line that I draw using the paintEvent function, but it's returning wrong values when reading the position of the buttons. this stuff has been tried on simpler projects and it worked but when using several widget container things gets wrong I don't know why.
Image of project result:
Simpler projects:
code's header file:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QPainter>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
virtual void paintEvent(QPaintEvent* event);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
code's source file:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter paint(this);
QPen pen;
pen.setColor(QColor(56, 163, 220));
pen.setWidth(2);
paint.setPen(pen);
int xstart1 = ui->pushButton_4->pos().x() + ui->pushButton_4->width();
int ystart1 = ui->pushButton_4->pos().y() + (ui->pushButton_4->height() / 2);
int xfinish1 = ui->pushButton_6->pos().x();
int yfinish1 = ui->pushButton_6->pos().y() + (ui->pushButton_6->height() / 2);
paint.drawLine(xstart1, ystart1, xfinish1, yfinish1);
int xstart2 = ui->pushButton_5->pos().x() + ui->pushButton_5->width();
int ystart2 = ui->pushButton_5->pos().y() + (ui->pushButton_5->height() / 2);
int xfinish2 = ui->pushButton_7->pos().x();
int yfinish2 = ui->pushButton_7->pos().y() + (ui->pushButton_7->height() / 2);
paint.drawLine(xstart2, ystart2, xfinish2, yfinish2);
}
code's ui:
<?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>590</width>
<height>435</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QWidget" name="widget" native="true">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_3">
<property name="text">
<string>PushButton</string>
</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>268</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QFrame" name="frame">
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QPushButton" name="pushButton_4">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_5">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>183</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<layout class="QVBoxLayout" name="verticalLayout_4">
<item>
<widget class="QPushButton" name="pushButton_6">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_7">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="widget_2" native="true">
<layout class="QVBoxLayout" name="verticalLayout_5">
<item>
<widget class="QTableWidget" name="tableWidget"/>
</item>
</layout>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QWidget" name="widget_3" native="true">
<layout class="QVBoxLayout" name="verticalLayout_6">
<item>
<widget class="QPushButton" name="pushButton_8">
<property name="text">
<string>PushButton</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>590</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>

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>

Link QLabel to variable (two different classes) in Qt C++

Currently working on getting threading to work with Qt C++ along with using the clearest method to solve the problem. Below is some code to start 3 threads and count to 10000. What i have at the moment is when u press the start and stop buttons the counters do work (using qDebug). However what I want to do is link the counter variable to 3 labels so that when the counter goes up the label for each thread does too (however had no luck with connect as not sure how to link class methods (specifically ui->label->settext to Thread::get_time())).
Currently I am stuck on the final part, as can't find a way to link to label from inside thread.cpp if anyone can help that would be great. As you can imagine gotten a bit lost and not sure where to go from here.
object.h
#ifndef OBJECT_H
#define OBJECT_H
#include <QObject>
#include <QDebug>
#include <QThread>
#include <QApplication>
#include <QMutex>
class Object : public QObject
{
Q_OBJECT
private:
int timealive;
public:
explicit Object(QObject *parent = 0);
void setup(QThread &thread, QObject &object);
void set_time(int number);
int get_time();
bool Stop;
signals:
public slots:
void worker();
};
#endif // OBJECT_H
dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private slots:
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void on_pushButton_3_clicked();
void on_pushButton_4_clicked();
void on_pushButton_5_clicked();
void on_pushButton_6_clicked();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
Dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_pushButton_clicked()
{
ui->label->setText(QString::number(12));
}
void Dialog::on_pushButton_2_clicked()
{
}
void Dialog::on_pushButton_3_clicked()
{
}
void Dialog::on_pushButton_4_clicked()
{
}
void Dialog::on_pushButton_5_clicked()
{
}
void Dialog::on_pushButton_6_clicked()
{
}
Main.cpp
#include "dialog.h"
#include "object.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w;
w.show();
QThread thread;
Object thread_object;
thread_object.setup(thread,thread_object);
return a.exec();
}
object.cpp
#include "object.h"
Object::Object(QObject *parent) :
QObject(parent)
{
}
void Object::setup(QThread &thread,QObject &object)
{
object.moveToThread(&thread);
thread.start();
connect(&thread,SIGNAL(started()),this,SLOT(worker()));
}
void Object::worker()
{
for(int i = 0; i < 10000; i++)
{
QMutex mutex;
QMutexLocker locker(&mutex);
this->set_time(i);
qDebug() << i;
if(this->Stop)
{
break;
}
}
}
void Object::set_time(int number)
{
timealive = number;
}
int Object::get_time()
{
return timealive;
}
Dialog.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>286</width>
<height>168</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>10</x>
<y>40</y>
<width>261</width>
<height>25</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Number</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_2">
<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_3">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_4">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget_2">
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>261</width>
<height>25</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Number</string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer_3">
<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_5">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_6">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>9</x>
<y>9</y>
<width>261</width>
<height>25</height>
</rect>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Number</string>
</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">
<property name="text">
<string>Start</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_2">
<property name="text">
<string>Stop</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
Cheers ION
P.s changed code to reflect that I am now using the correct way for threading.

Qt QTimeSpan Error LNK2019

I am using Windows 7, QCreator, Qt 5.0 and my PC is x64.
I get the following errors while using QTimeSpan:
mainwindow.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) public: __cdecl QTimeSpan::~QTimeSpan(void)" (__imp_??1QTimeSpan##QEAA#XZ) referenced in function "private: void __cdecl MainWindow::on_pushButton_clicked(void)" (?on_pushButton_clicked#MainWindow##AEAAXXZ)
mainwindow.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) class QTimeSpan __cdecl operator*(class QTimeSpan const &,int)" (__imp_??D#YA?AVQTimeSpan##AEBV0#H#Z) referenced in function "class QTimeSpan __cdecl operator*(int,class QTimeSpan const &)" (??D#YA?AVQTimeSpan##HAEBV0##Z)
mainwindow.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) class QTimeSpan __cdecl operator-(class QTime const &,class QTime const &)" (__imp_??G#YA?AVQTimeSpan##AEBVQTime##0#Z) referenced in function "private: void __cdecl MainWindow::on_pushButton_clicked(void)" (?on_pushButton_clicked#MainWindow##AEAAXXZ)
mainwindow.obj:-1: error: LNK2019: unresolved external symbol "__declspec(dllimport) class QTime __cdecl operator+(class QTime const &,class QTimeSpan const &)" (__imp_??H#YA?AVQTime##AEBV0#AEBVQTimeSpan###Z) referenced in function "private: void __cdecl MainWindow::on_pushButton_clicked(void)" (?on_pushButton_clicked#MainWindow##AEAAXXZ)
debug\Midpoint3_1.exe:-1: error: LNK1120: 4 unresolved externals
I have tried adding the Qt/libs directory to paths in my computer's 'Environment Variables' but failed.
Here's the source code:
//Midpoint3_1.pro
#-------------------------------------------------
#
# Project created by QtCreator 2013-07-01T03:58:17
#
#-------------------------------------------------
QT += core gui
QT += widgets
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Midpoint3_1
TEMPLATE = app
SOURCES += main.cpp\
mainwindow.cpp\
HEADERS += mainwindow.h \
../../../../../../../../Qt/Qt5.0.2/5.0.2/msvc2012_64/include/QTimeSpan/qtimespan.h
FORMS += \
mainwindow.ui
//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 slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtGui>
#include <QtCore>
#include "QTimeSpan/qtimespan.h"
#include <QTime>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->horizontalSlider,SIGNAL(valueChanged(int))
,ui->percentage,SLOT(setValue(int)));
}
void MainWindow::on_pushButton_clicked()
{
QTime vtime1 = ui->time1->time();
QTime vtime2 = ui->time2->time();
QTimeSpan vspan = vtime2 - vtime1;
int vpercentage = ui->percentage->value();
QTime vtime3 = vtime1 + (vpercentage/100) * vspan;
//ui->time3->setText(QString );
}
MainWindow::~MainWindow()
{
delete ui;
}
//main.h
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
There's also a mainwindow.ui, here's the source code:
<?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>284</width>
<height>259</height>
</rect>
</property>
<property name="windowTitle">
<string>Time Midpoint Calculator</string>
</property>
<widget class="QWidget" name="centralWidget">
<widget class="QWidget" name="layoutWidget">
<property name="geometry">
<rect>
<x>20</x>
<y>10</y>
<width>241</width>
<height>191</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Time 1</string>
</property>
</widget>
</item>
<item>
<widget class="QTimeEdit" name="time1"/>
</item>
</layout>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="text">
<string>Time 2</string>
</property>
</widget>
</item>
<item>
<widget class="QTimeEdit" name="time2">
<property name="time">
<time>
<hour>12</hour>
<minute>0</minute>
<second>0</second>
</time>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QSlider" name="horizontalSlider">
<property name="minimumSize">
<size>
<width>128</width>
<height>19</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>20000</width>
<height>19</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>1</number>
</property>
<property name="value">
<number>50</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string>Percentage</string>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="percentage">
<property name="maximumSize">
<size>
<width>60</width>
<height>22</height>
</size>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
<item>
<widget class="QPushButton" name="pushButton">
<property name="text">
<string>Calculate</string>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="label_4">
<property name="text">
<string>Output Time</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="time3">
<property name="text">
<string>6:00:00 AM</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>284</width>
<height>21</height>
</rect>
</property>
<widget class="QMenu" name="menuHelp">
<property name="title">
<string>Help</string>
</property>
<addaction name="actionThe_Algorithm"/>
<addaction name="actionThe_Algorithm_2"/>
<addaction name="actionAbout_Midpoint"/>
</widget>
<addaction name="menuHelp"/>
</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"/>
<action name="actionThe_Algorithm">
<property name="text">
<string>What is 'Fraction'?</string>
</property>
</action>
<action name="actionThe_Algorithm_2">
<property name="text">
<string>The Algorithm</string>
</property>
</action>
<action name="actionAbout_Midpoint">
<property name="text">
<string>About Midpoint</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
See here for the source code for qtimespan.h.
And here's how the program looks like:
I think you are trying to include and link to "C" libraries in your C++ application. If your QT is a C library, then calling convention would be __cdecl, but C++ may be looking for linking with __stdcall or someother convention.
In such a scenario if you are sure you are using a C library to link with your CPP app, then include your C headers with
#ifdef _cplusplus
extern "C" {
#endif
#include < your hearder here > //for example QtGui and QTCore etc headers here
#ifdef _cplusplus
}
#endif
This will ensure you will be able to C library without any issues from CPP application