I am having a main widget and multiple child widgets to show.
I add all child widgets to the main widget layout and call show of only one child and hide others.
In windows PC this works fine. But in android the child widget appears even if hide is invoked. Can anyone suggest where I'm wrong.
#include "mainframe.h"
#include "ui_mainframe.h"
MainFrame::MainFrame(QWidget *parent) :
QWidget(parent),
ui(new Ui::MainFrame)
{
ui->setupUi(this);
m_pMainLayout = ui->gridLayout;
initialize();
}
MainFrame::~MainFrame()
{
delete ui;
}
void MainFrame::initialize()
{
m_pStartupScreen = new StartupScreen(this);
m_pSystemScreen = new SystemScreen(this);
m_pMainLayout->addWidget(m_pStartupScreen);
m_pMainLayout->addWidget(m_pSystemScreen);
connect(m_pStartupScreen, SIGNAL(reportsButtonClick()),
this, SLOT(handleUserOptionReports()));
connect(m_pStartupScreen, SIGNAL(systemButtonClick()),
this, SLOT(handleUserOptionSystem()));
connect(m_pStartupScreen, SIGNAL(salesButtonClick()),
this, SLOT(handleUserOptionSales()));
m_pSystemScreen->hide();
m_pStartupScreen->show();
connect(m_pSystemScreen, SIGNAL(closeInvoked()), m_pStartupScreen, SLOT(show()));
}
m_pStartupScreen and m_pSystemScreen appears in android devices, ie, both child widgets appears overlapped.
Related
I have a ScrollArea which contains a frame to hold a layout. By pressing a button (Plusbutton below) I add new Widgets to the layout in the ScrollArea.
After adding several Items the Widgets get smaller and cut off. I want the layout to get bigger with added Widgets and want be able to scroll further down to see the added content.
[Edit]
I have constructed those widgets in Qt designer so i cant provide that much code. But i hope this will help you understand my problem.
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->scrollArea->setWidgetResizable(true);
ui->verticalLayout_6->insertWidget(0,ui->blueframe,Qt::AlignTop);
}
void MainWindow::on_addwidget_pressed()
{
ui->verticalLayout_6->insertWidget(2,new Toolbar);
}
I am trying to build an application that after getting some user input on the first window, pops up another window and displays some results. However, even though the menubar is visible on the first window, the menubar does not appear on the second window. The two windows are objects of different classes, but both classes are inherited from QMainWindow.
I have tried using the menuBar() function which returns a pointer for the menubar to add menus (this works for the first window). I also tried creating a new menubar object which didn't help either.
//MapWindow.h
class MapWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MapWindow(QWidget *parent = nullptr);
~MapWindow();
private:
QAction *vehicleAct;
QAction *missionAct;
QAction *backAct;
QMenu *toolMenu;
};
//MapWindow.cpp
MapWindow::MapWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MapWindow)
{
ui->setupUi(this);
setWindowState(Qt::WindowMaximized);
vehicleAct = new QAction("Vehicle Selection");
vehicleAct->setShortcut(Qt::CTRL + Qt::Key_V);
missionAct = new QAction("Mission Selection");
missionAct->setShortcut(Qt::CTRL + Qt::Key_M);
backAct = new QAction("Back");
backAct->setShortcut(Qt::CTRL + Qt::Key_B);
toolMenu = menuBar()->addMenu("Tools");
toolMenu->addAction(vehicleAct);
toolMenu->addAction(missionAct);
toolMenu->addAction(backAct);
}
MapWindow::~MapWindow() {
delete ui;
}
When I use the same code in the WelcomeWindow class which is also inherited from QMainWindow it works perfectly. However it doesn't even show a menubar in this second window.
I managed to find the problem. One of my widgets (QScrollArea) was located in the top left corner of the screen which was stopping the whole menubar from displaying for some reason. Moving the QScrollArea down a little bit has solved the problem.
I am attempting to create a specialised QDockWidget, with some contents, that I can use in other Qt5 UIs. To do this, I have created a QDockWidget subclass complete with a UI form, called SpecialDockWidget. The contents (a QTreeWidget) are added in the UI form.
In my main UI, I have added SpecialDockWidget as a QDockWidget promotion, have promoted the desired dock widget, and everything compiles OK. However, when I run the application my promoted dock widget contains the title of the SpecialDockWidget in its title bar, but the contents remain empty. This only happens if the dock widget is made part of the main UI (whether floating or attached), and the dock widget displays the contents successfully if it is instantiated on its own as a top-level widget.
The Qt documentation says the following with regards to QDockWidget::setWidget():
If the dock widget is visible when widget is added, you must show() it explicitly.
Note that you must add the layout of the widget before you call this function; if not, the widget will not be visible.
I have tried calling show() on both the SpecialDockWidget and the contents, and have set the layout myself, but the contents still don't show up.
Can anyone tell me what I might be doing wrong?
EDIT: Some photos showing what's going on:
Dock widget code:
#include "specialdockwidget.h"
#include "ui_specialdockwidget.h"
#include <QVBoxLayout>
SpecialDockWidget::SpecialDockWidget(QWidget *parent) :
QDockWidget(parent),
ui(new Ui::SpecialDockWidget)
{
ui->setupUi(this);
}
SpecialDockWidget::~SpecialDockWidget()
{
delete ui;
}
Main window code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// This produces the top-level dock widget
// SpecialDockWidget* w = new SpecialDockWidget();
// w->show();
}
MainWindow::~MainWindow()
{
delete ui;
}
The QDockWidget is created in the Designer so it's not very clear how the tree is added to the QDockWidget. If the tree is simply a child of the QDockWidget it's not correct. You must add the tree to the QDockWidget using QDockWidget::setWidget().
I suggest to not use the Designer to create a subclass of QDockWidget because it seems not possible to add the content correctly. You can do something like this instead.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDockWidget *dw = new QDockWidget(this);
QTreeWidget* tw = new QTreeWidget(dw);
dw->setWidget(tw);
addDockWidget(Qt::LeftDockWidgetArea, dw);
dw->show();
}
Of course, if you need to put inside a dock widget a more complex widget, you can create the content with the Designer as a simple QWidget subclass and add it to the dock widget in the same way.
I think your main window's constructor should look like, for example:
MainWindow::MainWindow(QWidget *parent)
:
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
SpecialDockWidget *w = new SpecialDockWidget();
// Add dock widget to the specified area of main window.
addDockWidget(Qt::LeftDockWidgetArea, w);
}
I want to do something fairly simple : add a custom widget to Qt designer that would basically be a scrollArea containing a custom vertical layout(I added some code to the vertical layout in order to handle its objects for my projects).
The idea would be to represent a vertical menu that would be on the side of my screen
What I have done so far
I created the custom widget plugin and my custom layout.
My custom widget codes looks like this:
#include "menuwidget.h"
MenuWidget::MenuWidget(QWidget *parent) :
QScrollArea(parent)
{
this->setWidgetResizable(true);
QWidget* layoutHoldingWidget= new QWidget(this);
layout= new MenuLayout();
layout->setSizeConstraint(QLayout::SetMinAndMaxSize);
layout->addStretch(1);
layoutHoldingWidget->setLayout(layout);
this->setWidget(layoutHoldingWidget);
}
If I add manually to the layout (in the constructor code) some buttons
for(int i =0;i<20;i++)
layout->addWidget(new QPushButton(this));
It does work and I can see my scrollArea containing some buttons, which is almost what I want.
What I want
I would like to be able to add these buttons directly via Qt designer: the user would first drag the empty MenuWidget on the main window, then would drag QPushButtons on my custom widget exactly like he would do on a regular vertical layout.
Is that possible?How could I do such a thing?
Thank you ! :)
Edit 1
What I was missing was the "scrollAreaWidgetContents" widget that is always created when you drag and drop a QScrollArea. I did a similar thing by adding a widget (let's call it containerWidget) to my custom scrollArea in its domXml function, which enables me to drag and drop widgets on my scroll Area like I wanted to do.
BUT there's still something I can't figure out : I want the containerWidget to have a customLayout (myCustomLayout) . If I add it in the domXml function, I get the following line in the terminal :
Designer:The layout type 'MyCustomLayout' is not supported,
defaulting to grid.
So it means that I can't tell designer to use my custom layout to place my widgets, which is kind of sad :D
Is there any way to "cheat" here?
There are two things to consider:
1) Overwrite in the class you derive from QDesignerCustomWidgetInterface the function to return true
bool isContainer() const { return true; }
This tells QtDesigner that the widget can contain children. (In Qt nearly any Widget can contain any widget as child, but QtDesigner tries to restrict it in a sensible way - e.g. you cant add children to a QLabel in QtDesigner)
2) Implement childEvent of your Widget. Probably in your case it would add Widgets added in QtDesigner to a layout.
Here is a core I've implemented to try this out. I've created a skeleton using "Qt Widget Plugin" Wizard in QtCreator and modified a little bit.
Don't forget to build as release, for the compiler/Qt-version of your QtDesigner , to copy the .dll and .lib files in \plugins\designer directory and to restart QtDesigner!
verticalplugin.cpp
//all other functions remained as created by QtCreator wizard
bool VerticalMenuPlugin::isContainer() const
{
return true;
}
VerticalMenu.h
#ifndef VERTICALMENU_H
#define VERTICALMENU_H
#include <QtGui/QWidget>
#include <QtGui/QVBoxLayout>
class VerticalMenu : public QWidget
{
Q_OBJECT
protected:
virtual void childEvent ( QChildEvent * event );
public:
VerticalMenu(QWidget *parent = 0);
};
#endif
VerticalMenu.cpp
#include "verticalmenu.h"
#include <QChildEvent>
VerticalMenu::VerticalMenu(QWidget *parent) :
QWidget(parent)
{
setLayout (new QVBoxLayout);
}
void VerticalMenu::childEvent ( QChildEvent * event )
{
if ( event->added() )
{
QWidget * newChild = qobject_cast<QWidget *>(event->child());
if ( newChild )
{
layout()->addWidget( newChild );
}
}
}
I hope' it would help as a starting point.
Qt 4 does not support custom layout plugins for designer, so I couldn't achieve what I wanted to do. I will instead use a Vertical Layout and try to implement the additional features that were supposed to be in the custom layout code in the widget code.
I want to make a list of toolbuttons in QT. The toolbuttons should appear in a scollarea. This list should appear when a pushbutton is clicked. I have made the code and it works, exept that I have to push the pushbutton twice in order to let the list appear. Here is my code:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
find_btn.setParent(ui->centralWidget);
find_btn.setGeometry(480,250,130,132);
viewport.setLayout(&scrollLayout);
scrollArea.setParent(ui->centralWidget);
scrollArea.setGeometry(0,116,339,404);
scrollArea.setWidget(&viewport);
connect(&find_btn,SIGNAL(clicked()),this,SLOT(import()));
}
void MainWindow::import()
{
button.setCheckable(true);
button.setMinimumSize(317,60);
button2.setCheckable(true);
button2.setMinimumSize(317,60);
scrollLayout.addWidget(&button);
scrollLayout.addWidget(&button2);
viewport.adjustSize();
}
So when I push the "find_btn", the scrollarea with the buttons inside should appear. At the moment the scrollarea with buttons appears, but only after I click the "find_btn" twice.
I guess I have to update the scrollarea or something like that. Maybe the connect is causing problems? Can anybody help?
There are a couple of options you could try:
viewport.update();
or
scrollArea.viewport()->update();
or
QApplication::processEvents( QEventLoop::ExcludeUserInputEvents );
or any combination of them.
Probably the GUI is not redrawn until a redraw is forced by pressing the button again.