I'm using Qt 6.4 on Visual Studio 2022, I'm trying to understand how to add a new .ui to an existing project.
For example, I have a project with a mainwindow.ui, when I open it on Qt Designer and create a new .ui window from:
[Qt Designer] File -> New -> Main Window -> Create
I added some widgets to this new window and saved it to disk with the name new_window.ui.
How do I include it in my current project? I tried #include "new_window.ui" but It throws a lot of compiler syntax errors.
What I'm trying to achieve is access the widgets from new_window.ui inside of my MainWindow class:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
ui.setupUi(this);
// access the 'ui' from new_window.ui here
// new_window_ui.pushButton-> ...
}
I have seen that this ui generally is a private class member, there's no problem in having the new_window.ui ui public.
What is the correct way to achieve it?
I have been able to include the new ui file by creating it on a new project and copying the generated ui_new_window.h file plus her class header:
// new_window.h
#pragma once
#include "stdafx.h"
#include "ui_new_window.h"
QT_BEGIN_NAMESPACE
namespace Ui { class new_windowClass; };
QT_END_NAMESPACE
class new_window : public QWidget
{
Q_OBJECT
public:
new_window(QWidget *parent = nullptr) : QWidget(parent), ui(new Ui::new_windowClass())
{
ui->setupUi(this);
}
~new_window() { delete ui; };
Ui::new_windowClass *ui;
};
Related
I need to create a new window over top of my current program (I'm attempting a dialog in this case) when a button is clicked. I have this working, but I am having trouble editing the content of the Dialog. As far as I'm aware, no .ui file is created for this and it is only being created when I connect the button to the function.
I have tried using a QMessageBox but was unable to resize the window how I needed. And still ran into the issue of adding the other elements.
void MyNameSpace::openInfoDialog()
{
QDialog* Dialog = new QDialog(this);
Dialog->setWindowTitle("View Stuff");
Dialog->setMinimumSize(500,250);
Dialog->adjustSize();
DialogRunner* msgRunner = new DialogRunner(Dialog, this);
msgRunner->safeExec();
}
This is my connect
connect(_Widget.InfoBtn, SIGNAL(clicked(bool)), this, SLOT(openInfoDialog()));
This code does produce a dialog on click, but I need to be able to add things like labels etc to it. I also use QT Designer as my WYSIWYG.
What can I do to create the new window from a button click and have it filled with other text etc ?
I have this working, but I am having trouble editing the content of
the Dialog
You can add ui files in your project:
Using that option Qt Creator will make a class with cpp and h files and a ui file in which you can add other widgets as you're used to.
use the import directives to use your class where you need it like you did in the code above and you will have your ui file available.
Then connect the clicked signal of your button with the slot of your dialog class. You can do that in the constructor of the class that holds the button.
You can read this approach more in detail in the book C++ GUI Programming
with Qt 4
on chapter 2 : Creating Dialogs.
It is available for free on the web. It uses Qt4, but in Qt5 it works the same way around.
EDIT: Here is a minimal example that shows you where you can use the needed parts: a mainwindow with a button on it (in the ui file). a Dialog class which also has a ui file (with several widgets on it). When clicking the button on the mainwindow, the dialog form is shown. Thjs is what I asked you for before. It makes it easier to communicate / test.
pro file
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = test
TEMPLATE = app
SOURCES += \
dialog1.cpp \
main.cpp \
mainwindow.cpp
HEADERS += \
dialog1.h \
mainwindow.h
FORMS += \
dialog1.ui \
mainwindow.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();
}
mainwindow.h
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
};
**mainwindow.cpp**
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog1.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
Dialog1* dialog = new Dialog1(this);
connect( ui->pushButton_1, SIGNAL(clicked()), dialog, SLOT(show()));
}
MainWindow::~MainWindow()
{
delete ui;
}
dialog1.h
namespace Ui {
class Dialog1;
}
class Dialog1 : public QDialog
{
Q_OBJECT
public:
explicit Dialog1(QWidget *parent = nullptr);
~Dialog1();
private:
Ui::Dialog1 *ui;
};
#endif // DIALOG1_H
dialog1.cpp
#include "dialog1.h"
#include "ui_dialog1.h"
Dialog1::Dialog1(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog1)
{
ui->setupUi(this);
}
Dialog1::~Dialog1()
{
delete ui;
}
I am doing an Application on Qt for my Internship and I have a problem.
The purpose of my Application is that I have a card connected by USB to my computer that sends CAN message.
I made an application in C++ on visual studio that received those CAN messages and printed them on the console with the help of a callback.
What I want to do know is to do the same thing but with a GUI application on Qt using the functions that I previously made (I didn't used classes in my visual studio project).
Iadded all my .cpp and .h files from my visual studio project into my QT project
So here is mainwindow.h file where I didn't changed anything. I just added a textLabel on my form.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
The main.cpp is very basic.
MainWindow.cpp :
Here is the constructor when I open the communication
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//Function created in Library.
open_com(...)
}
open_com opens the communication and call the callback each time a message is received
Definition of the callback
void callback (message id )
{
Here I want to call my TextLabel from my application
}
And my problem in this application is I don't know how to access my application from a function that is not part of the MainWindow class.
If someone already had this kind of problem and has the solution I would be very gratefull !
Thank you.
This is about a Qt 5.3.2 project buildt using CMake.
I have designed a QMainWindow using the Qt Designer, leading
to main.ui.
CMakeLists.txt (the almost complete thing may be
found here where I already posted it for a different question:
Linking and UIC order in a CMake Qt project )
already takes care of calling UIC so I have my hands on ui_main.h.
ui_main.h offers the class Ui::MainWindow with the plain form information
where all the buttons and stuff should be and the method *void setupUi(QMainWindow MainWindow).
Now my workflow (is it even a feasible one?) goes like this:
I build a totally new header file Form_main.h:
// Form_main.h
[..]
class Form_main : public MainWindow, public QMainWindow
{
Q_OBJECT
privat slots:
void on_some_event();
[..]
};
The class uses said auto-generated MainWindow::setupUi(this) to 'get in shape' and QMainWindow to be, well, a QMainWindow with all that stands for.
But now I am in a dilemma: Either I remove the Q_OBJECT macro call leading to connect(..) no longer recognizing that Form_main has signal slots, or
I keep the Q_OBJECT leading to the infamous
undefined reference to `vtable for display::Form_main'
error while linking the project.
Now, there have been, in fact, people with similar issues.
Naming some links:
http://michael-stengel.com/blog/?p=103
Qt Linker Error: "undefined reference to vtable"
Undefined reference to vtable... Q_OBJECT macro
Qt vtable error
A hint I got from the last one: "MOC must generate code for ui_main.h and the generated code must be compiled and linked."
In any case, these answers all seem to boil down to 'running qmake again'. Well, I use CMake all the way wanting my project to configure and compile after exactly
cmake .
make
What I did try was deleting everything in and below the build directory
(including every auto-generated file) and then running cmake . && make;.
Sadly that did not help. I am afraid this is my second noob question today... would you bear with me once more?
=== AFTER TRYING GREENWAYS ANSWER I PROVIDE MORE DETAILS. ===
Here is the autogenerated ui_main.h
/********************************************************************************
** Form generated from reading UI file 'main.ui'
**
** Created by: Qt User Interface Compiler version 5.3.2
**
** WARNING! All changes made in this file will be lost when recompiling UI file!
********************************************************************************/
#ifndef UI_MAIN_H
#define UI_MAIN_H
#include <QtCore/QVariant>
#include <QtWidgets/QAction>
[.. more Widget Includes ..]
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QAction *action_exit;
[.. more sub widgets like that .. ]
void setupUi(QMainWindow *MainWindow)
{
[ .. Setting up the form. Harmless code. .. ]
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
[ .. completely harmless .. ]
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAIN_H
Reading all this and incorporating your post right now I am at
// form_main.h
#ifndef MHK_FORM_MAIN_H
#define MHK_FORM_MAIN_H
#include <QMainWindow>
#include "ui_main.h"
[..]
namespace Ui { class MainWindow; }
namespace display
{
class Form_main : public QMainWindow
{
Q_OBJECT
private:
ostream* stdout;
ostream* stderr;
Ui::MainWindow* uiMainWindow;
/** Called by the constructor. Sets up event connections and other
* preliminary stuff the qt Designer is overtasked with. */
void setup_form();
[..]
public:
explicit Form_main(QWidget* parent = 0);
~Form_main();
private slots:
void exit_program();
};
}
#endif
And my cpp
// form_main.cpp
#include "ui_main.h"
#include "form_main.h"
[..]
using namespace Ui;
namespace display
{
void Form_main::setup_form()
{
QObject::connect(uiMainWindow->action_exit, SIGNAL(triggered()), this, SLOT(exit_program()));
[..]
}
Form_main::Form_main(QWidget* parent) : QMainWindow(parent)
{
uiMainWindow = new Ui::MainWindow();
uiMainWindow->setupUi(this);
[..]
#if defined(Q_OS_SYMBIAN)
this->showMaximized();
#else
this->show();
#endif
}
Form_main::~Form_main()
{
delete uiMainWindow;
}
[..]
Form_main::exit_program()
{
this->close();
(*stdout) << "Thanks for playing " << getProgramName() << endl;
}
}
Ok. I see (partly) the problem. Just create a widget class like this:
.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();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
.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;
}
This is how the QtCreator creates ui-Widgets. "ui_MainWindow.h" is your generated .h file.
Thanks for all your help! However, the problem was in CMakeLists.txt after all. The comment of Chris Morlier on Undefined reference to vtable pointed me to the solution.
The pertinent passage goes:
For Qt users: you can get this same error if you forget to moc a header
I simply had to add the header form_main.h into this line:
QT5_WRAP_CPP(qt_H_MOC ${qt_H} "${DIR_SRC}/include/form_main.h")
I'm developing an application with Qt, a framework with which I'm not at all familiar, and I'm attempting to hide and show a DockWidget that I created using designer.
Unlike many of the seemingly similar questions about hiding and showing dockwidgets in Qt is that I made my widget entirely with Qt Designer, so I don't know how to link much of the code I've found in these questions' answers. Essentially, I have no mention of a dockwidget in my *.cpp files, but I do in my .ui file.
How can I incorporate this Designer-created dockwidget into my code to make it visible and invisible?
Sorry for such a nooby question.
Thanks,
erip
Wenn you build your application, qmake generates h from your ui files. So for instance ui_dlg_about.ui is translated into a ui_dlg_about.h automatically. Usually in a folder calles GeneratedFiles or something like that. You can then create an acutal customisable dialog class which you use in your application by creating something along the following:
dlg_about.h
#include "ui_dlg_about.h"
#include <QDialog>
class dlg_about : public QDialog, protected Ui::ui_dlg_about
{
Q_OBJECT
public:
dlg_about(QWidget* = 0);
public slots:
void toggle_dockwidget();
};
dlg_about.cpp
#include "dlg_about.h"
dlg_about::dlg_about(QWidget* parent) : QDialog(parent)
{
setupUi(this);
QObject::connect(this->somebutton, SIGNAL(clicked()), this, SLOT(toggle_dockwidget()));
}
void dlg_about::toggle_dockwidget()
{
if(something){
this->dockwidget->setVisible(true);
}else{
this->dockwidget->setVisible(false);
}
}
It is also possible for your dialog to not be derived from ui_dlg_about but having it as a member:
dlg_about.h
#include "ui_dlg_about.h"
#include <QDialog>
class dlg_about : public QDialog
{
Q_OBJECT
public:
dlg_about(QWidget* = 0);
public slots:
void toggle_dockwidget();
protected:
Ui::ui_dlg_about ui;
};
dlg_about.cpp
#include "dlg_about.h"
dlg_about::dlg_about(QWidget* parent) : QDialog(parent)
{
setupUi(this->ui);
QObject::connect(this->ui.somebutton, SIGNAL(clicked()), this, SLOT(toggle_dockwidget()));
}
....
I am new to Qt Framework...
I want to display a .png pic in my Form1.ui ,
so I dragged and dropped a Graphic view from the widget box then
I placed test.png in the same directory (inside the project folder)
and i did this in the code
//Form1.cpp
#include "form1.h"
#include "ui_form1.h"
Form1::Form1(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form1)
{
ui->setupUi(this);
ui->Pic1->setStyleSheet("background-image: url(test.png)");
}
Form1::~Form1()
{
delete ui;
}
//Form1.h
#ifndef FORM1_H
#define FORM1_H
#include <QWidget>
namespace Ui {
class Form1;
}
class Form1 : public QWidget
{
Q_OBJECT
public:
explicit Form1(QWidget *parent = 0);
~Form1();
private:
Ui::Form1 *ui;
};
#endif // FORM1_H
It compiled perfectly but the pic didn't appear ,
What did I Wrong ?
this is my qrc :
The Widget you should use to show pictures is a QLabel. You can do it directly from QtCreator, by setting its pixmap property.
As others said, you should first create a resource file and then add the image to that resource file. To create a Qt Resource File, go to the menus: File > Qt > Qt Resource File.
EDIT To do it programatically:
//names starting with : means that they are on a resource file,
//otherwise in the filesystem
QPixmap * mypix = new QPixmap(":/karim/test.png");
ui->your_label->setPixmap(mypix);
delete mypix;
If you have the png in your resources, maybe change your background-image: tag:
ui->Pic1->setStyleSheet("background-image: url(:/test.png)");
You need to add the image to a resource file: http://doc.qt.io/qt-5/resources.html