qt layout()->setSizeConstraint - qt

I have a problem with the layout () in Qt 5.
I want to make a dynamic variable dialog.
![enter image description here][1]
Below is the code for the constructor:
SortDialog :: SortDialog (QWidget * parent)
     : QDialog (parent)
{
     setupUi (this);
     SecondaryGroupBox-> hide ();
     TertiaryGroupBox-> hide ();
     layout () -> setSizeConstraint (QLayout :: SetFixedSize);
     setColumnRange ('A', 'Z');
}
The project is built successfully, but when you start receiving a signal from the operating system.
Signal: SIGSEGV
Purpose: Segmentation fault
If you delete a row
layout () -> setSizeConstraint (QLayout :: SetFixedSize);
The program works.
Please, help me.
P.s.:This is an example from the book c++ GUI Programmming with Qt 4 (page 31)

I was having the same problem.
I just solved it.
Probably you don't want the answer after two years, but I really want to write about this somewhere, because there is nothing about this little issue on the web.
The problem was that Qt Designer didn't generate code to set dialog's layout.
I just opened ui_sortdialog.h and found that out of SortDialog a widget was created. Than with this widget a layout would be created. The layout is called gridLayout_4, and every widget and layout of the form are added to this one. When I added to function retranslateUi line SortDialog->setLayout(gridLayout_4); everything worked. Generated code created layout and did everything what needed to be done, but it left SortDialog without any reference to the layout, therefore layout() returned zero.

That's because you didn't create a layout.
Go back to designer and click the form and choose lay out in grid.
If you don't do this, the layout would be 0 and the program will crash.

You have to create a layout, like QVBoxLayout.
QVBoxLayout *layout = new QVBoxLayout;
layout->setSizeConstraint (QLayout :: SetFixedSize);
setLayout(layout);

I fixed this with changing in Designer Form. Make sure that the layout in the Qt Designer is good. Especially "Form -> Adjust Size" at the end. (in the book page 33; creating a "Form-> Lay Out in a Grid"). Use the original code from the book.

Related

Qt shortcut for custom context menu

I have been reading though a couple of examples and post but I just cannot figure out how to add a shortcut to my custom context menu. My GUI has several elements. One of them is a treeView. For the elements in my treeView I would like to have a custom context menu.
My first approach was according to this tutorial here. The context menu itself worked but the shortcuts cannot work if you create the actin within the show function.
So my second approach was according to this tutorial. But still my shortcuts do not work and if I use the context menu all actions are called twice...
Since I did not find a tutorial or code example, which matches my case, I hope that someone here can explain to me how this is correctly done in theory. Adding a shortcut to an action for a custom context menu.
Where do I have to declare my action?
What needs to be the parent of the action?
On which widget do I need to call addAction?
Thanks for any hints.
Another way is to add your action also to the parent widget (or main window widget). As mentioned in this reply, adding the same action to multiple widgets is fine and it's the way QActions are supposed to be used.
Example with custom HtmlBrowser class deriving from QTextBrowser:
Ctrl+U shortcut works for this code:
HtmlBrowser::HtmlBrowser(QWidget * parent) : QTextBrowser(parent)
{
viewSourceAct = new QAction(tr("View/hide HTML so&urce"), this);
viewSourceAct->setShortcut(tr("Ctrl+U"));
viewSourceAct->setCheckable(true);
parent->addAction(viewSourceAct);
connect(viewSourceAct, &QAction::triggered, this, &HtmlBrowser::viewSourceToggle);
}
and Ctrl+U shortcut does not work with this code (same as above, but without parent->AddAction(...)):
HtmlBrowser::HtmlBrowser(QWidget * parent) : QTextBrowser(parent)
{
viewSourceAct = new QAction(tr("View/hide HTML so&urce"), this);
viewSourceAct->setShortcut(tr("Ctrl+U"));
viewSourceAct->setCheckable(true);
connect(viewSourceAct, &QAction::triggered, this, &HtmlBrowser::viewSourceToggle);
}
Curiously, parent in this case is another widget (tab widget), not MainWindow. Still, adding parent->addAction() helps. And, unlike your suggested answer, it works even when connecting action to simple methods, without slots. Works for me in Qt 5.15.0. Not quite sure why it works, though. Perhaps, the widget the action is added to must be permanent for shortcuts to work? Looks like a bug in Qt.
Thanks to Scheff's hint I got it working. I do not now if this is really the correct way but this works for me.
The action needs to be declared in the constructor of your GUI class (e.g. MainWindow):
actionDel = new QAction(tr("delete"), this);
actionDel->setShortcut(QKeySequence(Qt::Key_Delete));
connect(actionDel, SIGNAL(triggered()), this, SLOT(actionDel_triggered()));
The triggered signal needs to be connected to a slot. Hint: if you create the slot do not use on_ACTIONNAME_triggered, this will interfere with the designer and cause a connection error.
Next add the action to a custom menu
fileContextMenu = new QMenu(this);
fileContextMenu->addAction(actionDel);
And to the widget
ui->treeView->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->treeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showDirContextMenu(QPoint)));
ui->treeView->addAction(actionDel);
All in the constructor of your GUI class.
To show the context menu use the following code in slot used in the above connect:
QModelIndex index=ui->treeView->indexAt(pos);
// Here you can modify the menu e.g. disabling certain actions
QAction* selectedItem = fileContextMenu->exec(ui->treeView->viewport()->mapToGlobal(pos));
If you do not have a slot for an action, the action can be also handled in the context menu slot, but this does not work with shortcuts!
if(selectedItem == actionOpen){
on_treeView_doubleClicked(index);
}

SIGSEGV when adding widget in Qt

I implemented example (chapter 2) from "Mastering Qt 5" book but the code crashes when adding widget to centralWidget's layout:
ui->centralWidget->layout()->addWidget(&mCpuWidget)
I suspect that the centralWidget does not have layout, hence it crashes but I don't know how to fix that?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
mCpuWidget(this)
{
ui->setupUi(this);
SysInfo::instance().init();
ui->centralWidget->layout()->addWidget(&mCpuWidget);
}
Here are two more classes which might help figure out the problem. Some of you might have the book too with all of the code (hence I mentioned it).
CpuWidget::CpuWidget(QWidget* parent):
SysInfoWidget(parent),
mSeries (new QPieSeries (this))
{
mSeries->setHoleSize(0.35);
mSeries->append("CPU Load", 30.0);
mSeries->append("CPU Free", 70.0);
QChart* chart = chartView().chart();
chart->addSeries(mSeries);
chart->setTitle("CPU Average Load");
}
This class creates and sets layout (QVBoxLayout)
SysInfoWidget::SysInfoWidget(QWidget *parent, int startDelayMs, int updateSeriesDelayMs) :
QWidget(parent),
mChartView(this)
{
mRefreshTimer.setInterval(updateSeriesDelayMs);
connect(&mRefreshTimer, &QTimer::timeout,
this, &SysInfoWidget::updateSeries);
QTimer::singleShot(startDelayMs,
[this] {mRefreshTimer.start();});
mChartView.setRenderHint(QPainter::Antialiasing);
mChartView.chart()->legend()->setVisible(false);
QVBoxLayout* layout = new QVBoxLayout(this);
layout->addWidget(&mChartView);
setLayout(layout);
}
I'm the co-author of the book "Mastering Qt 5" !
I guess your suspicion about the layout is correct:
ui->centralWidget->layout()->addWidget(&mCpuWidget);
Without any layout defined the returned item is null so you can't call the method layout().
If you have some errors during your learning you should refer to the final source code hosted on github here: https://github.com/PacktPublishing/Mastering-Qt-5
Take a look to the the file "Mastering-Qt-5/Chapter_02/MainWindow.ui":
<ui version="4.0">
...
<widget class="QWidget" name="centralWidget">
<layout class="QHBoxLayout" name="horizontalLayout"/>
</widget>
...
</ui>
As you can see for this project, a horizontalLayout of type QHBoxLayout is defined in the centralWidget. You can easily edit a ".ui" file with a text editor from Qt Creator with the following steps:
Right-click on "MainWindow.ui" in the Project hierarchy view
Select "Open-With"
Finally "Plain text editor"
Select "Form editor" when you want to come back to the WYSIWYG editor.
As suggested in other answers, the way to do it from C++ with the following line is also correct:
ui->centralWidget->setLayout(new QHBoxLayout());
Thank you for highlighting the lack of information about the layout here. I created an issue to add an errata about this topic.
Unless I have missed something in the code you have provided you haven't actually set your central widget. By default calling QMainWindow::centralWidget() returns a NULL pointer. You need to first call QMainWindow::setCentralWidget(QWidget* yourCentralWidget) before you call it. And yes, you also need to add a layout to it if you want to use layout()->addWidget(...). You can create an instance of a generic QWidget, set its layout, set is a central widget and then work with it.
You can fix your problem either by adding a layout in C++:
ui->setupUi(this);
SysInfo::instance().init();
ui->centralWidget->setLayout(new QVBoxLayout()); // Or any other layout class
ui->centralWidget->layout()->addWidget(&mCpuWidget);
Or in the UI Designer by using those buttons:
Note that for the buttons to be active you need to have at least 1 widget in your central widget and then select your central widget. You can then write:
ui->setupUi(this);
SysInfo::instance().init();
// One way
ui->centralWidget->layout()->addWidget(&mCpuWidget);
// Another way
ui->layout->addWidget(&mCpuWidget);
Finally you could also move your CpuWidget to the ui file using the "Promote to..." option in the contextual menu. In this case you would not need mCpuWidget but you could access it using something like ui->cpuWidget.
For more info read the Qt Designer manual:
Using Layouts in Qt Designer
Using Custom Widgets with Qt Designer

How can I open second qml page on button click

I use Qt 5.5.0 and Qt Creator 3.4.2 on Mac-book, I want to open second qml on button click, I want to develop application in which login page come and after login control move to next page.
I try suggestion of stackoverflow, but still I face problem to open next qml on button click.
I tried
button2.onClicked:{
var component = Qt.createComponent("test.qml")
var window = component.createObject(root)
window.show()
}
How can I create a new window from within QML?
In upper case error come related to root, ReferenceError: root is not defined. I gave root id in test.qml file.
I also tried many more example to solve to develop functionality. Please give brief idea or code to develop this functionality.
The code below works, Take note of the property status and the function errorString() – they will give you information in debugging (.e.g. "file not found" errors, components not ready, etc).
See these pages for background:
Dynamic QML Object Creation from JavaScript
Component QML Type
Window QML Type
function createWindows() {
var component = Qt.createComponent("Child.qml");
console.log("Component Status:", component.status, component.errorString());
var window = component.createObject(root, {"x": 100, "y": 300});
window.show();
}
For this type of ui I'd use [StackView][1] component that allows also animations between transitions. Other solution is to use a Loader component.

Next and previous control button in winAPI to go to next page (c++)

I am creating an winAPI application in c++ I have a photo in preview pane and I want to create two buttons NEXT and PREVIOUS on clicking them I will go to the next page .
Could you please give me the idea how to do that in c++ ??
Do I need to use QT libraray or it can be done using the in built function of WinAPI like -
HWND hwndButton1 = CreateWindow(L"BUTTON",L"NEXT",WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,550,800,100,30,m_hwndPreview,(HMENU)buttonid1,(HINSTANCE)GetWindowLong(m_hwndPreview, -6),NULL);
HWND hwndButton2 = CreateWindow(L"BUTTON",L"PREVIOUS",WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON,650,800,100,30,m_hwndPreview,(HMENU)buttonid2,(HINSTANCE)GetWindowLong(m_hwndPreview, -6),NULL);
and then using WM_COMMAND for both the button clicks.
Am I going right?
I just want my API application work like a .pdf extension file...as in PDF files we have up and down arrow and on clicking upon them we can go to the next page..In winAPIc++ I couldn't find any such arrow function.. please tell me if there is any such arrow up/down function present to go to next page (because I am very less interested in creating NEXT and PREVIOUS button using createwindow function.. It looks odd).
You have not mentioned what tools you are using, so we don't know if you have a resouce editor. You should research that in a forum appropriate for the tools. If you think writing one line of code to create a button is "very complicated" then you need a better tool.
If you do not want the buttons to appear on top of the picture then you need another place to put them. One common possibility is a toolbar. It is a strip for buttons along the top or bottom of the main window:
http://msdn.microsoft.com/en-us/library/windows/desktop/bb760435(v=vs.85).aspx
With a resource editor you can draw an arrow on the button. Without a resource editor you can set the button text to a unicode arrow:
SetWindowText(hwndButton1, L"\x25bc"); // down arrow, use 25b2 for up arrow
Most buttons (and other controls) are created using a resource editor, placing the controls on a dialog template or a toolbar resource. If you do that Windows will create the buttons when you create the dialog or toolbar. This method is much preferred because Windows will adjust the size of the buttons as required for the screen settings in use.
If you can't do that you must use CreateWindow as you are doing.
Finally it is done.. I have created the buttons neither using Qt or nor using any createWindowEx..The best and easy approach to follow is resource editor ...just put some button on dialog and use IDD_MAINDIALOG (in my case)
m_hwndPreview = CreateDialogParam( g_hInst,MAKEINTRESOURCE(IDD_MAINDIALOG), m_hwndParent,(DLGPROC)DialogProc, (LPARAM)this);
and then
BOOL CALLBACK AMEPreviewHandler::DialogProc(HWND m_hwndPreview, UINT Umsg, WPARAM wParam, LPARAM lParam)
{
switch(Umsg) // handle these messages
{ .........
}
....
}
and thats done. Very easy task.

Change the UI at run time using C++ only ( No QML )

I have screen 1 on which there is a SUBMIT button. On click of the submit button I want to load another screen 2. the UI of screen 2 is developed using only Qt C++. there is no QML document related to that.
On the click of the submit button I have called a function void DoSubmit(). In this function I have made a page object.
Page * PageObj = new Page();
In this PageObj I have added containers and other controls and constructed my UI for scene 2, now I try to set this page as my current scene using the following command:
Application :: instance()->setScene( PageObj );
by doing so my app getting crashed but when I remove the statement containing Application :: instance()->setScene( PageObj ) it does not crash.
What is the problem in this I am not able to figure out. Please help..
The scene should not be used for adding a page, just the first one. You would better use a navigationPane or a sheet.
See the doc:
https://developer.blackberry.com/cascades/documentation/ui/navigation/index.html

Resources