Qt - How to override a widget? - c++

I've created a form using the Qt designer which includes a QToolButton.
I can turn it using ui->favouriteToolButton.
I used the designer because it's much more simple then code all the gui.
Problem is that specifically for this ToolButton i want to code by creating its own class:
class FavouriteMenu : public QToolButton
{
Q_OBJECT
public:
explicit FavouriteMenu(QWidget *parent = 0);
//~FavouriteMenu();
private:
QMenu *menu; //MENU
QAction *addToBookmarkAct;
QAction *editBookmarkAct;
...
I want to be able to override ui->favouriteToolButton with a new instance of FavouriteMenu.
How can i do it?

Right click on the button in designer and select "Promote To..."
Under Promoted class name enter "FavouriteMenu"
Under Header File enter the filename of the .h file
Click "Add"
Click "Promote"

Related

Qt C++ Creating toolbar

I am learning Qt and trying some examples in the book "Foundations of Qt Development".
In the book, there is a section teaching Single Document Interface with an example creating a simple app like a notepad.
However I am having problem with toolbar creating.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle(QString("%1[*] - %2").arg("unnamed").arg("SDI"));
connect(ui->docWidget->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
createActions();
createMenu();
createToolbars();
statusBar()->showMessage("Done");
}
It is the constructor of the main window.
void MainWindow::createToolbars()
{
QToolBar* toolbar;
toolbar = addToolBar(tr("File"));
toolbar->addAction(anyaction);
}
This is how the book create the toolbar.
However, when I try to run the program, there are two toolbars created.
One is the toolbar created by the code and called "File"
Another is a blank toolbar created by the ui designer ie. *ui.toolbar.
In order to get rid of two toolbars, I tried using only the *ui.toolbar.
It's working. The code is shown below.
void MainWindow::createToolbars()
{
ui->toolBar->addAction(anyaction);
}
But I tried to create the toolbar by code only, ie. not adding a toolbar in the ui designer.
So I write this:
void MainWindow::createToolbars()
{
QToolBar* FileBar = this->addToolBar(tr("File"));
FileBar->addAction(anyaction);
}
However, there is a compile error.
The compiler use this function:
void QMainWindow::addToolBar(QT::ToolBarArea area, QToolBar * toolbar)
instead of what I want:
QToolBar * QMainWindow::addToolBar(const QString & title)
http://doc.qt.io/qt-5/qmainwindow.html#addToolBar-3
What is my mistake here?
When you removed QToolBar from MainWindow QtCreator automatically removed import of QToolBar class.
Just add this to the top of mainwindow.h:
#include <QToolBar>
And it is better to define QToolBar* FileBar in private section of MainWindow in mainwindow.h. Then you will be able to access it from any method of MainWindow class.
void MainWindow::createToolbars()
{
FileBar = this->addToolBar(tr("File"));
FileBar->addAction(anyaction);
}
When you see such message:
must point to class/struct/union/generic type
First of all try to include headers for necessary class.

Show QDialog create in QtDesigner

I created next to my MainWindow a second form as QDialog with the Qt Designer.
My problem is how to show this Dialog by click a Button in the MainWindow.
If I use following code it creates a newDialog but I want to use the form I created in Qt Designer. How I can embed it?
QDialog *myDialog = new QDialog;
myDialog->show();
First you need to create in QtDesigner a new dialog. In that dialog add all the stuff that you need and then save all the changes. The file that you will create will be a .ui. Add this file to your project.
After this create a header file and cpp file with the name that you want( it would be better if you use the same name as de ui file ). Then in the .h:
namespace Ui {
class QDialogExample;
}
class QDialogExample : public QDialog
{
Q_OBJECT
public:
explicit QDialogExample(QWidget *parent = 0);
~QDialogExample();
private:
Ui::QDialogExample *ui; // This will be the acces to the widgets defined in .ui
};
And then in the .cpp file:
QDialogExample::QDialogExample(QWidget *parent) :
QDialog(parent),
ui(new Ui::QDialogExample)
{
ui->setupUi(this); // This will init all the widgets
}
Then in the slot of the QAction or your custom button add the call to
QDialogExample pDialogExample = new pDialogExample( this );
pDialogExample->show();
Anyway, to learn how it works, an all the process it would be advisable to use QtCreator, this is very helpfull in the creation of the dialogs and all the widgets that you need.

Add QWidgetAction to QMenu through qtcreator/qtdesigner

I am wondering if there is a way to add QWidgetAction to QMainwindow->QMenuBar->QMenu using either qtcreator or qtdesigner.
I can add a widget through the code like that:
//ui->myMenu is QMenu in QMenuBar of QMainWindow
QWidgetAction *act = new QWidgetAction(ui->myMenu);
QLineEdit* edt = new QLineEdit("I am Line edit",ui->myMenu);
//setup edt ...
act->setDefaultWidget(edt);
ui->myMenu->addAction(act);
It compiles and works as expected.
However, I cannot achieve same behavior using ui designer - it only lets me add QAction and QMenu classes as parts of QMenuBar/QMenu, and does not give option to promote QAction to QWidgetAction. Is there a way to add QWidgetAction and a widget associated with it through designer to have them as part of Ui namespace and their properties editable through ui editor?
Unfortunately that's not possible.

QWidget - Not sure where to start

I'm doing a college project in QT with C++. I basically have it all done, but I kind of want to end of a flourish! At the endgame, you get to the last room and press the control panel and a keypad appears (which is a .ui layout created as a QWidget) - the access code is a randomly generated 4 digit number in an earlier room.
Anyways, I want to pop up the QWidget with the keypad, get the user to press 4 buttons - each button would return a QString - and then press the confirm button. If it matches, game ends. If not, returned to room.
I just have no idea how to call the widget! The API haven't really help as I don't see anyway to assign a .ui form to the QWidget object.
The .ui file is a resource file. If the setup you have does not do this for you automatically, then you must use the uic tool to convert the .ui file to c++ source code.
foo.ui -> ui_foo.h
This header contains a class that creates the widgets and has members to acces each of the members once they have been created.
class Ui_Foo {
setupUi(QWidget *) { ...
}
}
namespace Ui {
class Foo: public Ui_Foo {};
} // namespace Ui
An instance of Ui::Foo is placed in your FooWidget
// FooWidget.h
//
class FooWidget
: public QWidget {
FooWidget(QWidget *);
Ui::Foo mUi;
}
and its setupUi is called in the constructor of your FooWidget
// FooWidget.cpp
//
FooWidget::FooWidget(QWidget *parent)
: QWidget(parent)
{
mUi.setupUi(this);
}
The .ui form is a widget. Just call show() on it.

How to call created .ui design form in Qt with button.clicked() event?

I'm very new in Qt and I would like to ask how to call the created .ui designer form to be connected with the PushButton in MainWindow.
What I've done:
1. Created a new .ui design form (Forms.right click -> Add New -> Qt Designer Form) to the current project.
2. Designed an about dialog in the .ui form created.
3. Make a slot PushButton.clicked() in the MainWindow.
For all who have done programming in Qt, please help me solve this problem to connect the PushButton with the .ui form, so the PushButton can call/show the form created in the .ui.
Thanks for your attention.
Using .ui files is explained in Qt's documentation:
http://doc.qt.io/archives/qt-4.7/designer-using-a-ui-file.html
Summary:
The easiest way to handle an .ui file is to run it through uic (the User Interface Compiler) at compile time. This is done automatically if the .ui file is included in your project (.pro) file. ("Add New" probably has done this automatically in your case.) Then you only need to include the generated C++ header file in your source file. Its name should be something like "ui_nameoftheoriginaluifile.hpp". Of course, after that you need to instantiate the form defined in the .hpp file.
Edited to add:
There are several issues with your code, starting from its readability. I don't know if you have used an object-oriented language before, but a very basic rule in C++ is to begin class names with capital letters to make them easier to distinguish from objects and other variables. So the class names should be "About", "Parent", etc.
The compilation error is caused by using "about" instead of the name of the class actually used in the "ui_about.hpp" file - "MainWindow". (Which is determined by the name of the form you have used in the .ui file.)
If you are using Qt Creator: hold down the Ctrl key and click on the name of the file "ui_about.h" in the include directive. This will open it for inspection. Try to figure out how it works.
You also haven't defined the opDialog() function as a member of the "parent" class in "parent.cpp", which causes another compile-time error.
You also shouldn't be using a QMainWindow for an about dialog. QMainWindow is supposed to be the main window of your application - there shouldn't be any more instances of it.
So, about.h:
namespace Ui {
class MainWindow;
}
class about : public QMainWindow {
Q_OBJECT
public:
about(QWidget *parent = 0);
~about();
protected:
void changeEvent(QEvent *e);
private:
Ui::MainWindow *ui;
};
And the beginning of about.cpp:
#include "about.h"
#include "ui_about.h"
about::about(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}