Bogus widget in Qt Creator - qt

I'm a Qt newbie, working in Qt Creator 3.1.2 (Ubuntu Linux), Qt 5.3.1.
My program has a form with a button (pushButton) which changes the value of a text field (plainTextEdit) on being pressed. Both pushButton and plainTextEdit have been added in graphical mode. Connection between the button and its slot (on_pushButton_clicked()) has been set up via the graphical interface too.
The problem is, the program produces a bogus plainTextEdit, i.e. a different one, in the upper left corner, where the output goes to, while the "main" one stays clean. The question hence is, how I can avoid it? In general, how should I connect graphical widgets and their counterparts in the code? Here is my program:
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QPlainTextEdit>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
QPushButton *pushButton;
QPlainTextEdit *plainTextEdit;
};
#endif // MAINWINDOW_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();
}
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
plainTextEdit = new QPlainTextEdit(this);
// whenever I remove the previous line, I get SIGSEGV
setWindowTitle(tr("My test app..."));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
plainTextEdit->setPlainText("Some text here");
}

It's the widget you're creating in your constructor that is "bogus". The widgets you created in the forms editor belong to the Ui::MainWindow, you must not re-create them in your main window.
Remove this from your MainWindow:
QPushButton *pushButton;
QPlainTextEdit *plainTextEdit;
Remove the widget creation from the constructor:
plainTextEdit = new QPlainTextEdit(this);
Change your on_pushButtonClicked member to:
ui->plainTextEdit->setPlainText("Some text here");

Related

How to open other tab of same window using a pushbutton on qt?

I have a window. In this window I have a tab. In this tab I have two pages (page 1 & page 2). I have a pushButton on page 1. I one to go on page 2 using this pushButton. How to open other tab of same window using a pushbutton on qt?
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_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();
}
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_pushButton_clicked()
{
}
From the comments: One solution is to add an automatic slot in your main window class that executes when the button is clicked. In this slot have it change the current index of the QTabWidget.
For example the following should cycle throw the tabs every time you click the button:
void MainWindow::on_pushButton_clicked()
{
if (ui->tabWidget->count() > 1) {
ui->tabWidget->setCurrentIndex( (ui->tabWidget->currentIndex()+1) % ui->tabWidget->count() );
}
}

Qt Main Window not repainting MDI area

I have an application that have a main window with an MDI area that uses the whole window. When the application is opened it is not maximized. If i open the child window and then close it, the ghost of the window still shows. If i open a another child window and then move it across the MDI area you get copies of the window one on top of each other only in the area where the ghost was.
If i open the main window, then maximize it, open the child and maximize it, this problem disappears. Then a can get the main window to the original size, open and close child windows, move them around and the background is redrawn correctly.
Is there anything that can be done to solve this behavior?
Calling the mdi window:
void PriceAnalysisTool::on_actionImport_triggered()
{
importprocess = new ImportProcess(working, printer, ui->mdiArea);
importprocess->show();
}
And the initial part of the sub window:
ImportProcess::ImportProcess(DataBase *d, QPrinter *p, QWidget *parent) : QMdiSubWindow(parent), ui(new Ui::ImportProcess)
{
ui->setupUi(this);
Test program showing the same behavior:
main window:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include "subwindow.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_actionOpen_Window_triggered();
private:
Ui::MainWindow *ui;
SubWindow *subwindow;
};
#endif // MAINWINDOW_H
main window.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_actionOpen_Window_triggered()
{
subwindow = new SubWindow(ui->mdiArea);
subwindow->show();
}
subwindo.h
#ifndef SUBWINDOW_H
#define SUBWINDOW_H
#include <QWidget>
#include <QMdiSubWindow>
namespace Ui {
class SubWindow;
}
class SubWindow : public QMdiSubWindow
{
Q_OBJECT
public:
explicit SubWindow(QWidget *parent = 0);
~SubWindow();
private:
Ui::SubWindow *ui;
};
#endif // SUBWINDOW_H
subwindw.cpp
#include "subwindow.h"
#include "ui_subwindow.h"
SubWindow::SubWindow(QWidget *parent) : QMdiSubWindow(parent), ui(new Ui::SubWindow)
{
ui->setupUi(this);
}
SubWindow::~SubWindow()
{
delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
the ui for the main window has only has a MDI are and the a menu with a single item that calls the subwindow. The subwindow is a widget that has nothing on it.
{
QSqlQuery query;
query.exec("drop table C"+QString::number(markTime.toSecsSinceEpoch()));
query.exec("drop table C"+QString::number(markTime.toSecsSinceEpoch())+"T");
query.exec("drop table C"+QString::number(markTime.toSecsSinceEpoch())+"S");
query.exec("drop table C"+QString::number(markTime.toSecsSinceEpoch())+"F");
delete ui;
}

Qt: Modal from a modal (Mac)

I have a Qt modal dialog (a complex form) that needs to itself pop up a modal dialog (a QMessageBox with setModal(true)). This modal should be on top of the parent modal form, and prevent interaction.
This all works swimmingly up to a point - the second modal appears, and prevents interaction with the widgets in the parent.
However, the parent form can still receive focus - that is, I can click in it, and the window receives focus (even if I can't interact with the widgets). This becomes a problem if you task away to another application at this point - when you task back the QMessageBox is behind the parent which has focus (and you can't interact with the parent). Basically, you have to move the parent to reveal the QMessageBox before dismissing it.
Is there a way to have a modal on top of a modal on prevent this problem on Mac OS with window focus and tasking away? (Not tested other OS BTW).
Example code to reproduce the problem:
Dialog.cpp
pushButton is just a standard pushbutton.
#include "dialog.h"
#include "ui_dialog.h"
#include <QMessageBox>
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
QObject::connect(ui->pushButton, &QPushButton::clicked, this, &Dialog::showMeAModal);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::showMeAModal()
{
QMessageBox box(this);
box.setText(tr("modal"));
box.setModal(true);
box.setWindowFlags(box.windowFlags() | Qt::Popup);
box.exec();
}
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();
public slots:
void showMeAModal();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_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;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
#include "dialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
Dialog dialog(&w);
dialog.setModal(true);
dialog.show();
return a.exec();
}
I've tried:
Qt::Popup on the Message Box
Changing parent to MainWindow
Qt::WindowStaysOnTopHint on Message Box
...to no avail.

How to use qAction submenu in Qt

I want to implement simple commands like a qDebug() when I click on a sub menu in the mainwindow. I was referring to sample program given along with the Qt 5 IDE (...\Qt\Qt5.2.0\5.2.0\msvc2010\examples\widgets\mainwindows\menus), and using it, I managed to construct the code. I do not receive any compile time or run time errors.
I created the mainwindow.ui using the design mode. It has an object of the QAction class called actionInterval.
But when I click on it, nothing happens, I am not able to implement the command in void interval(). I guess I am not connecting properly. What am I missing here? Please advise.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
void createActions();
private slots:
void interval();
};
#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);
createActions();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::createActions()
{
ui->actionInterval = new QAction(tr("&Interval"), this);
ui->actionInterval->setStatusTip(tr("Set the interval for capturing delta & reference images"));
connect(ui->actionInterval, SIGNAL(triggered()), this, SLOT(interval()));
}
void MainWindow::interval()
{
qDebug()<<"inside interval qdialog";
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
void MainWindow::createActions()
{
ui->actionInterval->setStatusTip(tr("Set the interval for capturing delta & reference images"));
connect(ui->actionInterval, SIGNAL(triggered()), this, SLOT(interval()));
}
You shouldn't need that ui->actionInterval = new QAction(tr("&Interval"), this); line, the ui->setupUi() handles that for you, so it's potentially causing an incorrect reference so when you do click on it it's not firing correctly.

Connecting buttons to mainwindows slot

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

Resources