I want to forbid any action in the main window, including its closure. while open child
I try:
// child window
Settings::Settings(QWidget *parent) :
QWidget(parent),
ui(new Ui::Settings)
{
ui->setupUi(this);
((QWidget*)parent)->setEnabled(false); // or parent->setEnabled(false);
...
makes segmentation fault on Settings->show();
and I try send signal from Settings constructor/destructor
to MainClass slot
void MainClass::Enable(bool enable)
{
qDebug() << "detect signal enable"; //
this->setEnable(enable);
}
but signal wasn't sent.
ofcourse i connect Settings to MainClass)).
signal emiting works in any other function of Settings.
For child windows it would be better to inherit from QDialog (not QWidget) because the first one is designed specially for dialogs. From Qt docs:
The QDialog class is the base class of dialog windows.
The method you need is QDialog::exec(). It opens your dialog as a modal window which will block the input for other application windows until it is closed.
Related
I work with QT Creator 4.9.1 and i've made a gui with the designer. I have a MainWindow with a stackedWidget and round about 60 pages, inside my mainwindow i have a button, with the onButton_clicked signal i open a dialog(show picture) to insert a number to set the page the user want to see inside the mainwindow.
My Problem is that the SIGNAL comes from the Dialog with the name on_pushButton_Enter_clicked and my SLOT is inside my mainwindow with the name setCurrentIndex(). I,ve read the post's: "How to Connect Signal from MainWindow to Slot in Dialog" and "Qt connect mainwindow and dialog using signal and slot".
But that doesn't help me because my dialog doesn't know about my mainwindow and i don't know how i can connect them.
Signal:
Dialognummer_eingeben.h
...
signals:
void enterButtonPressed();
...
void Dialognummer_eingeben::on_pushButton_Enter_clicked()
{
QString text = ui->lineEdit_Dialognummer->text();
ui->lineEdit_Dialognummer->setText("");
this->reject();
emit enterButtonPressed();
}
Slot:
Terminal::Terminal(QWidget *parent) : QMainWindow(parent), ui(new Ui::Terminal)
{
ui->setupUi(this);
QObject::connect(&dialog, SIGNAL(enterButtonPressed()), this, SLOT(setCurrentIndex()));
}
void Terminal::setCurrentIndex()
{
int num = dianr.getNum();
QString strNum = QString::number(num);
switch(num)
{
....
}
}
Edit: 1. Add signal and slot code
2. Make some changes inside the code
inside my mainwindow i have a button, with the onButton_clicked signal i open a dialog(show picture) to insert a number to set the page the user want to see inside the mainwindow.
You have to additionally add a signal in your dialog class which should be emitted once enter button was pressed, using on_pushButton_Enter_clicked as a function is not enough. Add a signal in the dialog class, like "enterButtonPressed()" and emit it in the function on_pushButton_Enter_clicked.
Inside the mainwindow (at some point where the dialog is created) add this line:
connect(dialog, SIGNAL(enterButtonPressed()), this, SLOT(SlotNameWhichShouldGetCalled()));
EDIT: Even if the above solution should work, a better solution came to my mind.
You generally should use the QDialog::accepted signal to connect to (see https://doc.qt.io/archives/qt-4.8/qdialog.html#accept).
Concrete steps:
In on_pushButton_Enter_clicked() at the bottom of the code add accept() instead of this-reject() (I assume you want the dialog to be closed succesful and not as rejected?)
Connect to the QDialog::accepted() signal by adding
QObject::connect(&dialog, SIGNAL(accepted()), this, SLOT(setCurrentIndex()));
Additionally ensure that you have no error in the connect(...) function. If the signal/slot is not found or is not matching you should see something in your application output in Qt Creator
I have a checkbox with a slot called
void MainWindow::on_checkBoxPhaseUnwrap_stateChanged(int state)
This is automatically connected.
The constructor of MainWindow is like this
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
{
ui->setupUi(this);
setupWidgets();
}
In setupWidgets I set the value of the checkbox
ui->checkBoxPhaseUnwrap->setChecked(true);
However the slot is not called, and thus the data base in the background not updated.
Once the window is shown I can click on the checkbox and the slot is called as usual. Why is it not called when I call setChecked Note: In the gui designer the default value is already checked. Is this the reason?
In the gui designer the default value is already checked. Is this the reason?
Yes void QCheckBox::stateChanged(int state)
This signal is emitted whenever the checkbox's state changes, i.e., whenever the user checks or unchecks it.
That means it is not emitted if you try to change state from Qt::Checked to Qt::Checked.
Solution would be to emit signal yourself:
In setupWidgets add
emit ui->checkBoxPhaseUnwrap->stateChanged(Qt::Checked);
I need a QMainWindow layout to change depending on the number of cores.
Therefore I set it manually (not using the Design mode).
My question is:
After this layout was created, how can I refer to the widgets it contains?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//...
buildLayout();
//...
// Now I'd like to use something like this:
// ui->threadingTable->...
// However, it's not the member of ui
}
void MainWindow::buildLayout()
{
QWidget *window = new QWidget(this);
QTableView *threadingTable = new QTableView(window);
//...
QGridLayout *layout = new QGridLayout(window);
layout->addWidget(threadingTable, 0, 0);
//...
window->setLayout(layout);
this->setCentralWidget(window);
}
I can get the QLayoutItem out of this->centralWidget().
Or I can make all widgets in layout members of MainWindow class and access them directly.
However, I feel that neither of these is the right way.
Is there a way to pass the widgets to ui?
So that I could access them by calling
ui->threadingTable
Both options are fine. It is possible to get pointer to threadingTable from the main class member or directly from the objects hierarchy:
qDebug() << qobject_cast<QGridLayout *>(this->centralWidget()->layout())->itemAtPosition(0, 0)->widget();
qDebug() << this->centralWidget()->layout()->itemAt(0)->widget();
Of course, null verification may be required. You can also check this question QGridLayout: Getting the list of QWidget added.
The class Ui::MainWindow is automatically generated from the .ui xml form that can be generated in the Design mode: "Using a Designer UI File in Your Application"
Since the layout is constructed manually the .ui file and the ui instance is not needed at all. You can remove them from your project.
On the other hand, it is possible to use custom widgets even in the Design mode in .ui forms.
So, if you need some tricky object you can build the entire form in handy Design mode and then, for example, the standard QTableView may be promoted to your CustomTableView that is inherited from QTableView. That custom class may implement some special behavior.
The main Part of my Application is a Systray-Menu. For maintenance there should be a normal GUI.
My Problem is that now I have to create two Signal/Slot-Connections back to the MainWindow from each Tab. This is for minimizing the GUI and to update the Menu. I don't know how to do this.
I tried to connect with this->parent->parent from the ManageSession and ui_manag->session_ui->minimizeButton from MainWindow. I have a little knot in my head and am asking for help. Or should I re-think my design? I´m using only QtCreator 2.6.1 with Qt 4.8.4.
Screenshots of the GUI-Elements
This is the mainwindows.cpp:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle(QCoreApplication::applicationName());
QWidget *mainWidget = new QWidget;
QTabWidget *ui_manag = new ManageTab;
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(ui_manag);
mainWidget->setLayout(mainLayout);
setCentralWidget(ui_manag);
ui_manag->setCurrentIndex(0);
//Here comming Code to setup a TrayIcon, the Database and the Menus
}
The Tab is completely generated by the Designer:
ManageTab::ManageTab(QWidget *parent) :
QTabWidget(parent),
tab_ui(new Ui::ManageTab)
{
tab_ui->setupUi(this);
}
For each Setting I use the same GUI with multiple inheritance:
ManageSession::ManageSession(QWidget *parent) :
QWidget(parent),
session_ui(new Ui::ManageWidget)
{
session_ui->setupUi(this);
session_ui->manageLabel->setText(tr("Manage Session"));
connect(session_ui->addButton, SIGNAL(clicked()), this, SLOT(addButton_clicked()));
connect(session_ui->editButton, SIGNAL(clicked()), this, SLOT(editButton_clicked()));
connect(session_ui->deleteButton, SIGNAL(clicked()), this, SLOT(deleteButton_clicked()));
}
//Here follows the Functions for manipulating the TableView
// and emmiting a Signal to Update the Menu
Let's remake it in an answer (so you can accept it, hehe. j/k, to long for a comment):
First. As i said in comment:
You are inheriting without specifying access. So it defaults to private. That's why
ui_manag->session_ui->minimizeButton
wont allow you to access the button.
Second.
parent is a method, so It's: this->parent()->parent() or just parent()->parent() ;)
Again, it probably needs to inherit public. Not sure, tho.
That should work then.
Newbie here, I put a dock widget in a main window, and there is a button in this dock widget panel, now I want to connect, this button with a function defined in the main window, it threw out an error, what should I do? Thanks
connect
(
perfectPanel_->btn_AAA,
SIGNAL(clicked()),
this,
SLOT(on_actionAAA_triggered()),
Qt::UniqueConnection
);
Error message is
$PWD/ui_perfectPanel.h: In constructor ‘xixi::xixi()’:
$PWD/ui_perfectPanel.h:71:18: error: ‘QPushButton* Ui_perfectPanel::btn_AAA’ is inaccessible
$PWD/xixi/xixi.cpp:51:25: error: within this context
Note that I have already managed to connect this with a toolbar button in the main window (xixi.cpp), it works great.
This happens because your dock class, perfectPanel, inherits privately from the generated ui class Ui::perfectPanel:
class perfectPanel : public QWidget, private Ui::perfectPanel
You could make that inheritance public, but shouldn't. Instead you should make the signal part of the perfectPanel class, and route the internal signal from the button to that external signal:
class perfectPanel ... {
...
signals:
void AAA_clicked();
};
perfectPanel::perfectPanel() {
setupUi(this);
connect(btn_AAA, SIGNAL(clicked()), this, SIGNAL(AAA_clicked()));
}
(And in case you would ask, yes, you can connect 2 signals together).
Then you simply connect the new signal inside your main window class:
connect(perfectPanel_,
SIGNAL(AAA_clicked()),
this,
SLOT(on_actionAAA_triggered()),
Qt::UniqueConnection
);