I will be glad if you could help me a little.
So as it is in topic I have error trying to do Q_OBJECT::connect.
So my code is:
preferences.h:
#include <QDialog>
#include <QApplication>
#include <QCoreApplication>
namespace Ui {
class Preferences;
}
class Preferences : public QDialog
{
Q_OBJECT
public:
explicit Preferences(QWidget *parent = 0);
~Preferences();
private:
Ui::Preferences *ui;
};
preferences.cpp:
#include "preferences.h"
#include "ui_preferences.h"
Preferences::Preferences(QWidget *parent) :
QDialog(parent),
ui(new Ui::Preferences)
{
ui->setupUi(this);
}
Preferences::~Preferences()
{
delete ui;
}
mainwindow.h:
#include "preferences.h"
#include "addkierowca.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
Preferences *PreferencesWindow;
private:
/* some private methods */
void showPreferencesWindow();
And last but not least mainwindow.cpp:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->actionUstawiania, SIGNAL(triggered()), this, SLOT(showPreferencesWindow()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::showPreferencesWindow()
{
PreferencesWindow = new Preferences(this);
PreferencesWindow->show();
PreferencesWindow->exec();
}
I couldn't found anwser anywhere, and I know that there are almost same topics, but none of them helped me.
Thanks in advice.
You are using showPreferencesWindow as a slot in the connect so need to at it to a slot.
change to:
private slots:
void showPreferencesWindow();
At that point, moc (used by the makefile) will generate the correct code needed for connect to work correctly.
Related
I try to switch between two different Widgets in QT5.
The first problem was that my first window was visible in the background of my second window. I solve this with a check in "autoFillBackground". Now i can switch between them, but if i resize them it only resize the Main content.
Both Widgets have a grid layout.
Resize Problem
Im new at QT5, so is there a better way to make a switching between 2 widgets without this problem?
I try it with wMessages = new Messages(); and hide() but then my program crash after going back.
Code:
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "messages.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_btnMessages_clicked();
private:
Ui::MainWindow *ui;
Messages *wMessages;
};
#endif // MAINWINDOW_H
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnMessages_clicked()
{
wMessages = new Messages(this);
wMessages->show();
}
messages.h:
#ifndef MESSAGES_H
#define MESSAGES_H
#include <QWidget>
namespace Ui {
class Messages;
}
class Messages : public QWidget
{
Q_OBJECT
public:
explicit Messages(QWidget *parent = nullptr);
~Messages();
QString NewsGenerator();
private slots:
void on_bBack_clicked();
void on_pushButton_clicked();
private:
Ui::Messages *ui;
};
#endif // MESSAGES_H
messages.cpp:
#include "messages.h"
#include "ui_messages.h"
Messages::Messages(QWidget *parent) :
QWidget(parent),
ui(new Ui::Messages)
{
ui->setupUi(this);
}
Messages::~Messages()
{
delete ui;
}
void Messages::on_bBack_clicked()
{
this->close();
QWidget *parent = this->parentWidget();
parent->show();
}
Edit 1 - working Main Window Button (from G.M.´s answer):
void MainWindow::on_btnMessages_clicked()
{
wPlaner = new Planer();
QMainWindow::setCentralWidget(wPlaner);
}
Update (based on the comments):
The best solution was to use the QStackedWidget to navigate between the views.
Docu: https://doc.qt.io/qt-5/qstackedwidget.html#details
Example-Code for Button:
// return back to first view
void MainWindow::on_btnret_clicked()
{
ui->stackedWidget->setCurrentIndex(0);
}
I have a problem. I created two classes in my Qt project. One as the main window, and second as the settings dialog. My idea is to send the values from "Settings" to "MainWindow" (like from one TextEdit to another) but unfortunately, I have no idea how to do it. It's confusing me. I have read similar topics on the internet but none of them gives me a clear answer. Can someone help me understand the way how can I do it via example?
I have no useful code to place it here, so I will put the part of the source code and headers of mine.
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
[...]
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "settings.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow()
[...]
private:
Ui::MainWindow *ui;
[...]
};
#endif // MAINWINDOW_H
settings.cpp
#include "settings.h"
#include "ui_settings.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"
Settings::Settings(QWidget *parent) :
QDialog(parent),
ui(new Ui::Settings)
{
ui->setupUi(this);
}
settings.h
#ifndef SETTINGS_H
#define SETTINGS_H
#include <QDialog>
namespace Ui {
class Settings;
}
class Settings : public QDialog
{
Q_OBJECT
public:
explicit Settings(QWidget *parent = nullptr);
~Settings();
[...]
private:
Ui::Settings *ui;
[...]
};
#endif // SETTINGS_H
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
Use signals/slots mechanism to share values between two QObject.
For example:
The following code allows yout to send the value in a QLineEdit to another widget by clicking on a button:
class Widget1: public QWidget
{
Q_OBJECT
public:
Widget1(): QWidget(),
message(new QLineEdit())
{
QPushButton* button = new QPushButton("Send msg", this);
connect(button, &QPushButton::clicked, this, [=]() { emit this->sendMsg(message->text());}); // When you click on the button, it will emit the signal sendMsg
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(message);
layout->addWidget(button);
}
private:
QLineEdit* message;
signals:
void sendMsg(QString const& msg);
};
class Widget2: public QWidget
{
Q_OBJECT
public:
Widget2(): QWidget(),
display(new QLabel("Nothing to display", this))
{
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(display);
}
private:
QLabel* display;
public slots:
void receive(QString const& message)
{
display->setText(message); // When called, display the message in the label
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget* mainWidget = new QWidget();
QHBoxLayout* layout = new QHBoxLayout(mainWidget);
Widget1* w1 = new Widget1();
Widget2* w2 = new Widget2();
layout->addWidget(w1);
layout->addWidget(w2);
// When the signal sendMsg is emitted, call the slot receive
QObject::connect(w1, &Widget1::sendMsg, w2, &Widget2::receive);
mainWidget->show();
return app.exec();
}
There are multiple ways to achieve this.
For example you can provide the public Getter Methods in your dialog for provide value to the public and use them directly in the MainWindow to read those.
Or you can use Signals/Slots as stated above.
One example with Signal/Slots:
The SettingsWindow emits textEdit(QString) signal if Dialog Accepted, and MainWindow receives this signal via on_textEdit(QString) slot and writes it to its own text field:
SettingsWindow reading text input and emitting signal textEdit(QString):
MainWindow receiving signal via slot on_textEdit(QString):
And this is the code:
maindow.h
#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();
private slots:
void on_pushButton_clicked();
void on_textEdited(QString txt);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingsdialog.h"
#include <memory>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
auto dlg = new SettingsDialog{this};
connect(dlg, &SettingsDialog::textEdit, this, &MainWindow::on_textEdited);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->show();
}
void MainWindow::on_textEdited(QString txt)
{
ui->textEdit->setText(txt);
}
settingsdialog.h
#ifndef SETTINGSDIALOG_H
#define SETTINGSDIALOG_H
#include <QDialog>
namespace Ui {
class SettingsDialog;
}
class SettingsDialog : public QDialog
{
Q_OBJECT
public:
explicit SettingsDialog(QWidget *parent = nullptr);
~SettingsDialog();
signals:
void textEdit(QString txt);
private slots:
void on_buttonBox_accepted();
private:
Ui::SettingsDialog *ui;
};
#endif // SETTINGSDIALOG_H
settingsdialog.cpp
#include "settingsdialog.h"
#include "ui_settingsdialog.h"
SettingsDialog::SettingsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::SettingsDialog)
{
ui->setupUi(this);
}
SettingsDialog::~SettingsDialog()
{
delete ui;
}
void SettingsDialog::on_buttonBox_accepted()
{
emit textEdit(ui->textEdit->toPlainText());
}
More about Signal/Slots
OK, let's start again...
I've created an project (Qt Widget Application) with Qt Creator.
My project structure:
myproject.pro
Headers
dialogform.h
mainwindow.h
Sources
dialogform.cpp
main.cpp
mainwindow.cpp
Forms
dialogform.h
mainwindow.h
When I click on DialogForm pushbutton, I need to call the clear() function from MainWindow
In my code below, my project is running, but, the clear() function does not clear the lineedit.
Do anyone known how can i fix this?
Thank you very much!
dialogform.h
#ifndef DIALOGFORM_H
#define DIALOGFORM_H
#include <QDialog>
namespace Ui {
class DialogForm;
}
class DialogForm : public QDialog
{
Q_OBJECT
signals:
void clearMainWindow();
public:
explicit DialogForm(QWidget *parent = 0);
~DialogForm();
private slots:
void on_pbClearLineEdit_clicked();
private:
Ui::DialogForm *ui;
};
#endif // DIALOGFORM_H
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();
public slots:
void clear();
private slots:
void on_pbCallDialog_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
dialogform.cpp
#include "dialogform.h"
#include "ui_dialogform.h"
#include "mainwindow.h"
DialogForm::DialogForm(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogForm)
{
ui->setupUi(this);
}
DialogForm::~DialogForm()
{
delete ui;
}
void DialogForm::on_pbClearLineEdit_clicked()
{
connect(); // need help here. I'm using Qt 5.6.1
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialogform.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pbCallDialog_clicked()
{
DialogForm *dialogForm = new DialogForm(this);
dialogForm->show();
}
void MainWindow::clear()
{
ui->lineEdit->clear();
}
myfunction accesses an attribute of class myfile. Therefore it either needs to be a method of myfile as well, or it could be a friend function of the class myfile. In the latter case, however, you would need to give the relevant instance of myfile to myfunction as an argument. All usages of myfunction would need to be updated in either case.
The solution:
DialogForm::DialogForm(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogForm)
{
ui->setupUi(this);
connect(ui->pbClearLineEdit, &QPushButton::clicked, static_cast<MainWindow*>(parent), &MainWindow::clear);
}
I've set up a basic Qt-Widgets-Application (Qt 5.5 community) with a simple QWidget "MainWindow" and an additinal QWidget "SettingsScreen".
Within the "MainWindow", touchscreen-events (handled by OS) are working as expected, but after opening the "SettingsScreen" all touch-events are executed on the desktop until I close the "SettingsScreen" using mouse or keyboard.
Environment:
Ubuntu Studio 14.04.03
Qt 5.5 Open Source Edition
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <settingsscreen.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QWidget
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_btnExit_clicked();
void on_btnSettings_clicked();
private:
Ui::MainWindow *ui;
SettingsScreen *wSettingsScreen;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "settingsscreen.h"
#include "ui_settingsscreen.h"
MainWindow::MainWindow(QWidget *parent) : QWidget(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btnExit_clicked()
{
this->close();
}
void MainWindow::on_btnSettings_clicked()
{
wSettingsScreen = new SettingsScreen(parentWidget());
wSettingsScreen->show();
}
settingsscreen.h
#ifndef SETTINGSSCREEN_H
#define SETTINGSSCREEN_H
#include <QWidget>
namespace Ui {
class SettingsScreen;
}
class SettingsScreen : public QWidget
{
Q_OBJECT
public:
explicit SettingsScreen(QWidget *parent = 0);
~SettingsScreen();
private slots:
void on_pushButton_clicked();
void on_btnBack_clicked();
private:
Ui::SettingsScreen *ui;
};
#endif // SETTINGSSCREEN_H
settingsscreen.cpp
#include "settingsscreen.h"
#include "ui_settingsscreen.h"
SettingsScreen::SettingsScreen(QWidget *parent) :
QWidget(parent),
ui(new Ui::SettingsScreen)
{
ui->setupUi(this);
}
SettingsScreen::~SettingsScreen()
{
delete ui;
}
void SettingsScreen::on_btnBack_clicked()
{
this->close();
}
I've just started developing with Qt, so please forgive me if I'm missing something essential :)
Any help would by highly appreciated!!
Thank you in advance!
Actually the thing is QMainwindow or any base Widget of your application is able to properly synthesize the Unhandled touch screen events to Mouse events. So whenever you are creating a dialog/widget, make sure to set Mainwindow as there parent and in the constructor of the child widget use setParent(parent). Even I was facing this kind of Issue and this worked for me.
What I'm trying to do is to call an time consuming operation (MockClamWrapper::loadDatabase()) in a separate thread at the moment of creation of my window and then to update my window once the operation is completed. Here is the code that I have.
MockClamWrapper.h
class MockClamWrapper : QObject
{
Q_OBJECT
public:
MockClamWrapper();
~MockClamWrapper();
bool loadDatabase(unsigned int *signatureCount=NULL);
Q_SIGNALS:
void databaseLoaded();
};
MockClamWrapper.cpp
bool MockClamWrapper::loadDatabase(unsigned int *signatureCount){
QThread::currentThread()->sleep(10);
databaseLoaded();
return true;
}
MainWindow.h
#include <QMainWindow>
#include <QFileDialog>
#include "mockclamwrapper.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public slots:
void enableWindow();
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
MockClamWrapper *clam;
void initWindow();
};
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect((QObject*)clam, SIGNAL(databaseLoaded()),(QObject*)this,SLOT(enableWindow()));
QFuture<void> fut = QtConcurrent::run(this,&MainWindow::initWindow);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::initWindow(){
clam->loadDatabase(NULL);
}
void MainWindow::enableWindow(){
ui->checkFileButton->setEnabled(true);
}
The program compiles, but it crashes right after start. I assume that I do something wrong with slots and signals, but can't find my mistake.
The reason for crash is that you are not making any instance of the class MockClamWrapper. In the connect statement, you are referencing a pointer that points to nothing. Make a new object and then connect :
clam = new MockClamWrapper();
connect(clam, SIGNAL(databaseLoaded()), this, SLOT(enableWindow()));