I have a Qt program which was made without Qt Creator. And I want to improve the functionality: put all that i have now (QGridLayout, QLabels, QPushButtons and QCustomPlot) in one tab of QTabWidget and make another one tab with another layout and widgets. How should i do it correctly? I tried to create QTabWidget and add to it my QGridLayout with all stuff. Mb it is right way.
Tried to find some info but all are using creator for their projects. i dont like it and so i cant find examples of how can i push all ready functionality to qtabwidget
This is my main function:
int main(int argc, char **argv) {
QApplication a(argc, argv);
Smartcalc calc;
calc.resize(750, 500);
calc.show();
return a.exec();
}
This is my constructor:
Smartcalc::Smartcalc(QWidget *parent) : QWidget(parent) {
createWidgets();
initGraph(customPlot);
mainLayout = new QGridLayout;
addWidgetsToLayout(mainLayout);
setWindowTitle(tr("Smartcalc_v1.0"));
connectWidgets();
customWidgets();
}
So i need to create two tabwidgets and push my Smartcalc functionality in one of tabwidgets.
Related
I have QSplitter set as the central widget:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
mdiArea(new QMdiArea)
{
QWidget *widget = new QWidget;
widget->setMinimumSize(100, 100);
QSplitter *splitter = new QSplitter;
splitter->addWidget(mdiArea);
splitter->addWidget(widget);
setCentralWidget(splitter);
createActions();
}
void MainWindow::createSubwin()
{
QWidget *subwin = new QWidget(mdiArea);
subwin->setWindowTitle("Subwindow");
subwin->setMinimumSize(100, 100);
mdiArea->addSubWindow(subwin);
subwin->show();
}
void MainWindow::createActions()
{
QAction *actSub = new QAction("Add subwindow", this);
connect(actSub, SIGNAL(triggered()), SLOT(createSubwin()));
QMenu *winMenu = menuBar()->addMenu("Windows");
winMenu->addAction(actSub);
}
When I press maximize button of subwindow, the subwindow covers entire main window. Is there any way to prevent such behaviour and make subwindow occupy all the space of QMdiArea instead?
UPD: It looks like that the problem occurs only when at least one menu in main window's QMenuBar is present. Without menuBar everything works as expected:
https://www.qtcentre.org/threads/44457-QMdiSubWindow-maximizing-problem
Regarding the QSplitter, I gave OP the following hint:
Move the right part of the QSplitter into a dock widget (and drop the QSplitter), so that the left part is the only part of the QMainWindow::centralWidget(). This would mean to work with the existing class instead of against, and is probably easier to manage.
OP appreciated the hint with the dock widget but claimed the sub-window will still occupy the whole main window.
I must admit my lack of experience with MDI and made an MCVE to prove me myself right or wrong:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QMainWindow qWinMain;
qWinMain.setWindowTitle("QMainWindow - MDI - Dock");
qWinMain.resize(640, 480);
// MDI
QMdiArea qMDI;
qWinMain.setCentralWidget(&qMDI);
// MDI sub widget
QLabel qWinSub("MDI Sub-Window\nwidget");
qMDI.addSubWindow(&qWinSub);
// Dock
QDockWidget qDock;
qDock.setWindowTitle("Dock");
QLabel qLblDock("Dock\nwidget");
qDock.setWidget(&qLblDock);
qWinMain.addDockWidget(Qt::RightDockWidgetArea, &qDock);
qWinMain.show();
// runtime loop
return app.exec();
}
Output:
So, I cannot reproduce OPs claim—it works on my side.
My platform: Windows 10, VS2019, Qt5.15
I enhanced the first MCVE a bit to see how it works if MDI sub-windows are created after qWinMain.show() (what's expected as the usual case).
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QMainWindow qWinMain;
qWinMain.setWindowTitle("QMainWindow - MDI - Dock");
qWinMain.resize(640, 480);
// MDI
QMdiArea qMDI;
qWinMain.setCentralWidget(&qMDI);
// Dock
QDockWidget qWinDock;
qWinDock.setWindowTitle("Dock");
QWidget qDock;
QVBoxLayout qVBoxDock;
QPushButton qBtnNewMDISubWin("New Sub-Window");
qVBoxDock.addWidget(&qBtnNewMDISubWin);
qDock.setLayout(&qVBoxDock);
qWinDock.setWidget(&qDock);
qWinMain.addDockWidget(Qt::RightDockWidgetArea, &qWinDock);
// create sub-window
int i = 0;
auto createSubWin = [&]() {
++i;
QLabel* pQWinSub = new QLabel(QString("MDI Sub-Window\nwidget %1").arg(i));
pQWinSub->setWindowTitle(QString("MDI Sub-Window %1").arg(i));
qMDI.addSubWindow(pQWinSub);
pQWinSub->show();
};
// install signal handlers
QObject::connect(&qBtnNewMDISubWin, &QPushButton::clicked,
createSubWin);
// runtime loop
qWinMain.show();
return app.exec();
}
Output:
It still works on my side as expected.
Note:
I had to add the explicit pQWinSub->show(); after qMDI.addSubWindow(pQWinSub); (which was not necessary in the first MCVE). However, this is exactly how it's done by OP's code.
OPs reply:
It turns out that the problem occurs only when menuBar is present
Oha. How comes?
I extended my MCVE again to add a menu bar:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QMainWindow qWinMain;
qWinMain.setWindowTitle("QMainWindow - MDI - Dock");
qWinMain.resize(640, 480);
// menu
QMenuBar qMenuMain;
QAction qCmdFile("File");
QMenu qMenuFile;
QAction qCmdFileNew("New");
qMenuFile.addAction(&qCmdFileNew);
qCmdFile.setMenu(&qMenuFile);
qMenuMain.addAction(&qCmdFile);
qWinMain.setMenuBar(&qMenuMain);
// MDI
QMdiArea qMDI;
qWinMain.setCentralWidget(&qMDI);
// Dock
QDockWidget qWinDock;
qWinDock.setWindowTitle("Dock");
QWidget qDock;
QVBoxLayout qVBoxDock;
QPushButton qBtnNewMDISubWin("New Sub-Window");
qVBoxDock.addWidget(&qBtnNewMDISubWin);
qDock.setLayout(&qVBoxDock);
qWinDock.setWidget(&qDock);
qWinMain.addDockWidget(Qt::RightDockWidgetArea, &qWinDock);
// create sub-window
int i = 0;
auto createSubWin = [&]() {
++i;
QLabel* pQWinSub = new QLabel(QString("MDI Sub-Window\nwidget %1").arg(i));
pQWinSub->setWindowTitle(QString("MDI Sub-Window %1").arg(i));
pQWinSub->setFrameShape(QFrame::Box);
qMDI.addSubWindow(pQWinSub);
pQWinSub->show();
};
// install signal handlers
QObject::connect(&qCmdFileNew, &QAction::triggered,
createSubWin);
QObject::connect(&qBtnNewMDISubWin, &QPushButton::clicked,
createSubWin);
// runtime loop
qWinMain.show();
return app.exec();
}
Output:
Note:
I partly agree with OP:
Yes, the look of the maximized MDI is a bit different now. It looks like it occupies the whole client area of the main window but…
…the dock widget is still visible. I added a box to the QLabel (the top widget in the MDI sub-window) to illustrate this. In fact, the sub-window still occupies the central widget only (regardless what the look of its title bar suggests).
I'm trying to display a Q3DScatter graph in a Main Window designed with Qt Designer so I've added a widget to the main window but I don't know how to embed the graph object in this widget. I tried to create a widget "container" programmatically and embed the graph in it and then putting the widget in a QHBoxLayout (which has been added to the main window using Qt Designer) using the following code in my main window's constructor:
...
Q3DScatter *graph = new Q3DScatter();
QWidget *container = QWidget::createWindowContainer(graph);
ui->horizontal_layout->addWidget(container, 1);
But the window appears to be empty when executing. I'd really appreciate some help.
EDIT: Here's the full code of my main window constructor:
ResultsWindow::ResultsWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ResultsWindow)
{
ui->setupUi(this);
Q3DScatter *graph = new Q3DScatter();
QWidget *container = QWidget::createWindowContainer(graph);
ui->horizontal_layout->addWidget(container, 1);
}
And here's the main code:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ResultsWindow w;
w.show();
return a.exec();
}
EDIT 2: I forgot to specify that the horizontal layout is embedded in a GridLayout. I tried to create a new project and my code actually works perfectly when I add a horizontal layout directly to the main window. So could the problem be due to the GridLayout?
I'm trying to use Qt 5.5.1 QGraphicsBlurEffect in my project, but can't make it work on Mac:
I was trying to make a change by using PerformanceHint, QualityHint or AnimationHint, but didn't succeed. Using QGraphicsColorizeEffect I had the same issue, while QGraphicsOpacityEffect and QGraphicsDropShadowEffect, as well as everything on Linux worked perfectly fine:
How can I change my project file or code to make this graphics issue go away? Is it even possible?
TEMPLATE = app
TARGET = main
QT += widgets
SOURCES += main.cpp
#include <QtWidgets>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QMainWindow window;
QTextEdit *text = new QTextEdit;
text->setReadOnly(true);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(text);
QWidget *widget = new QWidget;
widget->setLayout(layout);
QGraphicsBlurEffect effect;
effect.setBlurRadius(3);
QLabel *test = new QLabel("TEST");
test->setGraphicsEffect(&effect);
(new QHBoxLayout(text))->addWidget(test, 0, Qt::AlignCenter);
window.setCentralWidget(widget);
window.show();
return app.exec();
}
I had a similar problem with QGraphicsOpacityEffect: blurred text and icons when it must be crisp sharp. Seems like a bug in Qt. My solution was to write my own small class containing everything I need with a proper rendering.
Well, you can try to fix Qt... good luck at reading source code of graphics effects. It is quite complicated with all it's dpr and transform matrix and rendering child widgets.
Code below
#include <QtWidgets>
#include <QGLWidget>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMainWindow w;
w.setCentralWidget(new QGLWidget(&w)); // w.setCentralWidget(new QWidget(&w));
QTreeWidget* tree = new QTreeWidget(&w);
QTreeWidgetItem* item0 = new QTreeWidgetItem(tree, QStringList("a"));
QTreeWidgetItem* item1 = new QTreeWidgetItem(tree, QStringList("b"));
tree->setContextMenuPolicy(Qt::CustomContextMenu);
QObject::connect(tree, &QTreeView::customContextMenuRequested, [](){
QMenu menu;
menu.addAction("a");
menu.exec(QCursor::pos());
});
QDockWidget* dock = new QDockWidget("Tree", &w);
dock->setWidget(tree);
w.addDockWidget(Qt::LeftDockWidgetArea, dock);
w.show();
return a.exec();
}
Compile and run it. It requires 2 right clicks to switch context menus among items. However, if I change QGLWidget to QWidget. It is fine. 1 right click can switch context menus among items. Any bugs??? Thanks a lot.
Some observations:
Switch the positions of the tree and the GL widget is ok, i.e. set the tree as the central widget and GL Widget as the one in the dock.
It seems the right click event goes to the central widget and then is blocked by the GL widget.
I am trying to add a label to the main window using Qt. Here is a piece of the code:
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
QWidget Main_Window;
QPixmap Image;
Image.load("1837.jpg");
QLabel i_label;
i_label.setPixmap(Image);
i_label.show();
QPushButton Bu_Quit("Quit", &Main_Window);
QObject::connect(&Bu_Quit, SIGNAL(clicked()), qApp, SLOT(quit()));
Main_Window.show();
return app.exec();
}
I've been having a very hard time figuring out how to properly add QLabels to QWidgets, I tried to set the Main_Window as the main widget using this method: app.setMainWidget(Main_Window) and the label was still outside the window. So how do I put labels into widgets using Qt?
hamza, this code worked fine for me:
#include <QtGui>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QWidget Main_Window;
QLabel i_label("Start", &Main_Window);
//i_label.setPixmap(QPixmap("1837.jpg"));
QPushButton Bu_Quit("Quit" , &Main_Window);
QObject::connect(&Bu_Quit , SIGNAL(clicked()), qApp , SLOT(quit()));
QVBoxLayout *vbl = new QVBoxLayout(&Main_Window);
vbl->addWidget(&i_label);
vbl->addWidget(&Bu_Quit);
Main_Window.show();
return app.exec();
}
I commented setting the image code to show you that the label was set correctly. Make sure your image is valid (otherwise you won't see the text). The trick here was that you need to use qt layouts like QVBoxLayout
Add the label to a layout widget and set the window layout to that layout.
Design note: its better to create your own MainWindow class, inheriting from QMainWindow for instance, and design it from the inside.
or even better, use QtCreator.
You can try:
QWidget window;
QImage image("yourImage.png");
QImage newImage = image.scaled(150, 150, Qt::KeepAspectRatio);
QLabel label("label", &window);
label.setGeometry(100, 100, 100, 100);
label.setPixmap(QPixmap::fromImage(newImage));
window.show();
this way you can even decide where to put the label and choose the image size.