So I'm making a web browser as my first Qt project (surprise!) and I'm wondering why calling setWindowState(Qt::WindowMaximized) is not changing window geometry. I have this code:
From mainwindow.h:
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
private:
Ui::MainWindow *ui;
};
From mainwindow.cpp:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// this->geometry() is the same here...
setWindowState(Qt::WindowMaximized);
ui->webView->setGeometry(0, 60, geometry().width(), geometry().height()-60);
// ...as it is here.
}
As you may be able to tell, I'm trying to start the application with the window maximized and the QWebView also maximized. Basically, whenever the main window is resized, I also want to call ui->webView->setGeometry with the update height and width. But MainWindow::geometry doesn't seem to be updating. What am I doing wrong?
I would have to double check, but your geometry might not get updated properly until your main window gets a show event.
However, I would suggest you put your QWebView inside of a layout instead of trying to size it manually every time your main window changes size.
Related
I'm really stuck on one problem that I want to solve. the problem is that I have a Class for QMainWindow which holds the Ui variable for that form. Now I want to be able to edit that Form using the Ui variable in that class on a QDialog cpp file. I probably sound really stupid and I really have no idea how I should explain this, but I have code which maybe can help.
MainWindow.h:
#include "ui_mainwindow.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
protected:
Ui::MainWindow *ui;
}
MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"
Dialog *dialog;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
dialog = new Dialog(this);
dialog->show();
}
QDialog.cpp:
#include "ui_mainwindow.h"
#include "mainwindow.h"
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
Ui::MainWindow *mainui;
void Dialog::on_pushbutton_clicked(){
mainui->label->setText("test");
}
So as you can see from the above code, it shows that I have a pointer to the Ui variable however its uninitialised, therefore it would lead to a SIGSEGV error, so how to do Initialize this pointer? any help here is highly appreciated, and even though this is probably really simple I just don't know what to do. (I have looked at other questions but I couldn't quite grasp what to do, so please explain what I am to do before linking me to a similar question. Also, I have left out the Dialog.h file as I didn't think it was needed, please tell me if I need to show it, thanks!).
Generally in C++ you should practice what is called encapsulation - keep data inside a class hidden from others that don't need to know about it. It's not good to have multiple pointers to the UI object as now all those other objects have to know how the main window UI is implemented.
In this case, what I would recommend is to use Qt's signals and slots mechanism to allow the dialog to tell the main window what you need it to do. That has the advantage that if you add more dialogs, or change how things are implemented in the main window, you don't need to alter the signal slot mechanism, and the details are hidden cleanly.
So - for your dialog, add a signal like this in the header file
class Dialog : QDialog
{
Q_OBJECT
signals:
void setTextSignal(QString text);
}
and in your main window header, add a slot.
class MainWindow : public QMainWindow
{
Q_OBJECT
public slots:
void setTextSlot(const QString &text);
}
now in your method where the button is pressed,
void Dialog::on_pushbutton_clicked()
{
emit setTextSignal("test");
}
and in your main window
void MainWindow::setTextSlot(const QString &text)
{
mainUi->label->setText(text);
}
The final part is to connect the signal and slot together, which you would do in your main window function where you create the dialog:
void MainWindow::on_pushButton_clicked()
{
dialog = new Dialog(this);
connect(dialog, SIGNAL(setTextSignal(QString)), this, SLOT(setTextSlot(QString)));
dialog->show();
}
You can see there are many advantages to this; the Dialog no longer needs a pointer to the main window UI, and it makes your code much more flexible (you can have other objects connected to the signals and slots as well).
Short answere - your can't! If you want to create a new instance of the ui, you would have to do:
MainWindow::Ui *ui = new MainWindow::UI();
ui->setupUi(this);
However, the this-pointer for a UI created for a QMainWindow based class must inherit QMainWindow - thus, you can't.
In general, it is possible if you create your Ui based on a QWidget instead of a QMainWindow, since both inherit QWidget.
Alternativly, you could try the following:
QMainWindow *subWindow = new QMainWindow(this);
subWindow->setWindowFlags(Qt::Widget);
MainWindow::Ui *ui = new MainWindow::UI();
ui->setupUi(subWindow );
//... add the mainwindow as a widget to some layout
But I would guess the result will look weird and may not even work in the first place.
I am new to Qt. I took an example from here http://doc.qt.io/qt-5/qtmultimediawidgets-player-example.html.
Now I want to integrate the player in the main window. I created a Qt Widgets application project, I thought, that I would just have to edit the main window code:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Player* player;
MainWindow::setCentralWidget(player);
}
But it doesn't work and I get the following error:
Starting /home/***/Documents/build-player-Desktop-Debug/player...
The program has unexpectedly finished.
/home/***/Documents/build-player-Desktop-Debug/player crashed
How can I integrate a custom widget which is written in code, without ui in a main window? Thank you in advance.
In your own MainWindow class you can add a widget to the layout of that MainWindow:
MyMainWindow::MyMainWindow(QWidget *parent) :
...
{
this->ui->setupUi(this);
QLabel *myLabel = new QLabel();
this->layout()->addWidget(myLabel);
}
Well, player can't be placed on the window if it is not initialized.
Write something like that :
Player *player = new Player();
I usually add a QWidget (or whatever widget type I'm extending) to my .ui-file in the designer and then promote it to the actual derived type. See the Qt docs for more info on promoting widgets. This means that I can set the base widget's properties and design the window as usual but still get an instance of my special class when the UI is instantiated.
MainWindow:MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
SomeStupidWidget *ssw = new SomeStupidWidget(this); /* important! don't forget about passing "this" as argument, otherwise this could cause a memory leak(Qt handles object's lifetime by means of it's "owner" mechanism)*/
layout()->addWidget(ssw);
}
I'm working on an app in C++/Qt I have used the design tool to design a Qdialog box.
The Dialog box is defined as below.
c++ file
#include "dialogwarning.h"
#include "ui_dialogwarning.h"
DialogWarning::DialogWarning(QWidget *parent) :
QDialog(parent),
ui(new Ui::DialogWarning)
{
ui->setupUi(this);
}
DialogWarning::~DialogWarning()
{
delete ui;
}
header file
#include <QDialog>
namespace Ui {
class DialogWarning;
}
class DialogWarning : public QDialog
{
Q_OBJECT
public:
explicit DialogWarning(QWidget *parent = 0);
~DialogWarning();
private:
Ui::DialogWarning *ui;
};
The source use it as below:
WarningDialog = new DialogWarning();
QLabel *label = new QLabel("File/Folder name already exist", WarningDialog);
label->setGeometry(WarningDialog->rect().center().x() - label->rect().width()/2,
WarningDialog->rect().center().y() - label->rect().height()*2,
WarningDialog->rect().width(),
WarningDialog->rect().height());
WarningDialog->exec();
I'm using exec instead of show because the exec primitive allow me to be stucked inside the dialog until a press on the "Ok" button.
What is strange is that the OK button is not working. I do not need any specific behavior just wait the OK press to continue to run the code.
Thanks
i'm not quite sure assuming u have connected everything. could be that the application is frozen.
why not put the calculation in a different thread and connect the same signal that shows the dialog to thread pause.
the signal of the ok pushbutten should be connected to close the dialog and thread resume...
I have a project which provides the user with a GUI via Qt. I designed it with the Qt Designer (integrated in the Qt Creator) and now I would like to add another window in order to let the user change settings.
Afaik I have to use a QWidget to create another window and now I'm wondering how I may edit this QWidget in Qt Designer because I am only able to design mainwindow.
My code looks like this:
mainwindow.hpp
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
// various slot calls
// action triggered when clicking an entry in the QMenu of mainwindow
void on_action_dummy();
private:
Ui::MainWindow *ui;
QWidget dummy;
};
mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
// various implementations of the slot calls in mainwindow.hpp
void MainWindow::on_action_dummy()
{
dummy.show();
}
Maybe I need a own class for my new window? Is QWindow even the right class for this task?
You need to add a new UI file as well as header/class. There's an option for this in the "New File" dialog in Qt Creator (Qt Designer Form Class under the "Qt" sub-category on the sidebar). Then you open that up and instantiate the class like MainWindow in your program's entry point (int main()). Something like:
MySettingsDialog *dialog = new MySettingsDialog(this);
dialog->show();
You need to be careful how you instantiate it--mainly making sure the object will survive when it leaves the current scope (e.g. using a pointer if you are calling this in a method inside your class). Also, how you show/exec your dialog can vary. This is usually the case when you want a blocking (modal) dialog instead of a new "window".
Edit: To handle the memory management, you can set the WA_DeleteOnClose attribute:
dialog->setAttribute(Qt::WA_DeleteOnClose);
I am trying to make a form with data table appear when the button is clicked on thr main form. However, in practice second form 'blinks' - appears less than on second - and then vanished. What could be the reason and how that should be fixed?
Here is the derived form header and source files' content:
#ifndef GOODTABLE_H
#define GOODTABLE_H
#include <QDialog>
#include <QSqlTableModel>
namespace Ui {
class GoodTable;
}
class GoodTable : public QDialog
{
Q_OBJECT
public:
explicit GoodTable(QDialog *parent = 0);
GoodTable(QDialog *parent,QSqlTableModel* model);
~GoodTable();
private:
Ui::GoodTable *ui;
};
#endif // GOODTABLE_H
#include "goodtable.h"
#include "ui_goodtable.h"
GoodTable::GoodTable(QDialog *parent) :
QDialog(parent),
ui(new Ui::GoodTable)
{
ui->setupUi(this);
}
GoodTable::GoodTable(QDialog *parent,QSqlTableModel* model) :
QDialog(parent),
ui(new Ui::GoodTable)
{
ui->setupUi(this);
ui->tableView->setModel(model);
}
GoodTable::~GoodTable()
{
delete ui;
}
The code creating second window:
void MainWindow::on_goodTable_clicked()
{
QSqlTableModel model;
initializeGoodModel(&model);
//! [4]
GoodTable view(NULL,&model);
view.setWindowFlags(Qt::Window);
view.setWindowModality(Qt::ApplicationModal);
view.show();
}
The problem is, that you have a local dialog object on the stack in your on_goodTable_clicked method. So you create the view, call show, which shows the dialog and immediately returns, then your view get's destroyed as you leave the function. If you make the dialog modal anyway, why not use QDialog's exec method intead of show. It shows the dialog and blocks the main window until you clicked the dialog's Ok or cancel button and then exec finally returns. When you want a non-modal dialog (meaning your main window works, while the dialog is open), you need to create your dialog dynamically (or make it a member of your main window, or both).