Clojure + Seesaw: Why doen't this GUI work? - clojure

I'm trying to create a project just like the seesaw example window-builder, I've created a project called my-gui-project, copied the code from src/window_builder/core.clj and src/window_builder/MyForm.java into my project and and changed line 31 where it says:
(let [form (identify (window_builder.MyForm.))]
into:
(let [form (identify (my_gui_project.MyForm.))].
Then, I ran the following commands: lein deps, lein compile and lein run -m my-gui-project.core and it returns the following error:
Exception in thread "main" java.lang.ClassNotFoundException: my_gui_project.MyForm, compiling:(my_gui_project/core.clj:31:24)
Why is this happening? The code is exactly the same, I've just changed the folder name.
This is the complete code:
core.clj:
(ns my-gui-project.core
(:gen-class)
(:use [seesaw.core])
(:require [seesaw.selector :as selector]))
; This is the interesting part. Note that in MyPanel.java, the widgets we're
; interested in have their name set with setName().
(defn identify
"Given a root widget, find all the named widgets and set their Seesaw :id
so they can play nicely with select and everything."
[root]
(doseq [w (select root [:*])]
(if-let [n (.getName w)]
(selector/id-of! w (keyword n))))
root)
(def states ["CA", "GA", "WA"])
(def defaults
{ :first-name "Laura"
:last-name "Palmer"
:street "123 Main St."
:city "Twin Peaks"
:zip "12345"
:state "WA" })
; A helper to create an instance of the form, annotate it for Seesaw and do
; some other initialization.
(defn my-form
[]
(let [form (identify (my_gui_project.MyForm.))]
; initialize the state combobox
(config! (select form [:#state]) :model states)
form))
; Now we just create the panel, initialize it to the defaults above with
; seesaw.core/value! and show it in a dialog. Note how, besides setting the
; names of the widgets, the code in MyForm.java is strictly for layout. All
; behavior, etc is done in Clojure.
(defn -main [& args]
(invoke-later
(let [form (value! (my-form) defaults)
result (-> (dialog :content form :option-type :ok-cancel) pack! show!)]
(if (= :success result)
(println "User entered: " (value form))
(println "User canceled")))))
project.clj:
(defproject my-gui-project "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "Eclipse Public License"
:url "http://www.eclipse.org/legal/epl-v10.html"}
:dependencies [[org.clojure/clojure "1.8.0"]
[seesaw "LATEST"]]
:main ^:skip-aot my-gui-project.core
:target-path "target/%s"
:profiles {:uberjar {:aot :all}})

Through testing I've found out that inside the MyForm.java there was also a reference to the project name. After changing the name inside the MyForm.java it works.
Edit: As referenced by #Carcigenicate in a post (now deleted), it is also necessary to add :java-source-paths ["src"] in project.clj
Original MyForm.java:
package window_builder;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JComboBox;
public class MyForm extends JPanel {
private JTextField firstName;
private JTextField lastName;
private JLabel lblStreet;
private JTextField textField;
private JLabel lblCity;
private JTextField textField_1;
private JLabel lblState;
private JComboBox comboBox;
private JLabel lblState_1;
private JTextField textField_2;
/**
* Create the panel.
*/
public MyForm() {
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{72, 134, 0, 0, 0, 0, 0};
gridBagLayout.rowHeights = new int[]{28, 28, 0, 0};
gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
setLayout(gridBagLayout);
JLabel lblFirstName = new JLabel("First Name:");
GridBagConstraints gbc_lblFirstName = new GridBagConstraints();
gbc_lblFirstName.anchor = GridBagConstraints.WEST;
gbc_lblFirstName.insets = new Insets(0, 0, 5, 5);
gbc_lblFirstName.gridx = 0;
gbc_lblFirstName.gridy = 0;
add(lblFirstName, gbc_lblFirstName);
firstName = new JTextField();
firstName.setName("first-name");
firstName.setColumns(10);
GridBagConstraints gbc_firstName = new GridBagConstraints();
gbc_firstName.gridwidth = 2;
gbc_firstName.anchor = GridBagConstraints.NORTH;
gbc_firstName.fill = GridBagConstraints.HORIZONTAL;
gbc_firstName.insets = new Insets(0, 0, 5, 5);
gbc_firstName.gridx = 1;
gbc_firstName.gridy = 0;
add(firstName, gbc_firstName);
JLabel lblLastName = new JLabel("Last Name:");
GridBagConstraints gbc_lblLastName = new GridBagConstraints();
gbc_lblLastName.anchor = GridBagConstraints.WEST;
gbc_lblLastName.insets = new Insets(0, 0, 5, 5);
gbc_lblLastName.gridx = 3;
gbc_lblLastName.gridy = 0;
add(lblLastName, gbc_lblLastName);
lastName = new JTextField();
lastName.setName("last-name");
lastName.setColumns(10);
GridBagConstraints gbc_lastName = new GridBagConstraints();
gbc_lastName.gridwidth = 2;
gbc_lastName.fill = GridBagConstraints.HORIZONTAL;
gbc_lastName.insets = new Insets(0, 0, 5, 0);
gbc_lastName.anchor = GridBagConstraints.NORTH;
gbc_lastName.gridx = 4;
gbc_lastName.gridy = 0;
add(lastName, gbc_lastName);
lblStreet = new JLabel("Street:");
GridBagConstraints gbc_lblStreet = new GridBagConstraints();
gbc_lblStreet.anchor = GridBagConstraints.EAST;
gbc_lblStreet.insets = new Insets(0, 0, 5, 5);
gbc_lblStreet.gridx = 0;
gbc_lblStreet.gridy = 1;
add(lblStreet, gbc_lblStreet);
textField = new JTextField();
textField.setName("street");
GridBagConstraints gbc_textField = new GridBagConstraints();
gbc_textField.gridwidth = 5;
gbc_textField.insets = new Insets(0, 0, 5, 0);
gbc_textField.fill = GridBagConstraints.HORIZONTAL;
gbc_textField.gridx = 1;
gbc_textField.gridy = 1;
add(textField, gbc_textField);
textField.setColumns(10);
lblCity = new JLabel("City:");
GridBagConstraints gbc_lblCity = new GridBagConstraints();
gbc_lblCity.anchor = GridBagConstraints.EAST;
gbc_lblCity.insets = new Insets(0, 0, 0, 5);
gbc_lblCity.gridx = 0;
gbc_lblCity.gridy = 2;
add(lblCity, gbc_lblCity);
textField_1 = new JTextField();
textField_1.setName("city");
GridBagConstraints gbc_textField_1 = new GridBagConstraints();
gbc_textField_1.insets = new Insets(0, 0, 0, 5);
gbc_textField_1.fill = GridBagConstraints.HORIZONTAL;
gbc_textField_1.gridx = 1;
gbc_textField_1.gridy = 2;
add(textField_1, gbc_textField_1);
textField_1.setColumns(10);
lblState_1 = new JLabel("State:");
GridBagConstraints gbc_lblState_1 = new GridBagConstraints();
gbc_lblState_1.insets = new Insets(0, 0, 0, 5);
gbc_lblState_1.gridx = 2;
gbc_lblState_1.gridy = 2;
add(lblState_1, gbc_lblState_1);
comboBox = new JComboBox();
comboBox.setName("state");
GridBagConstraints gbc_comboBox = new GridBagConstraints();
gbc_comboBox.insets = new Insets(0, 0, 0, 5);
gbc_comboBox.fill = GridBagConstraints.HORIZONTAL;
gbc_comboBox.gridx = 3;
gbc_comboBox.gridy = 2;
add(comboBox, gbc_comboBox);
lblState = new JLabel("Zip:");
GridBagConstraints gbc_lblState = new GridBagConstraints();
gbc_lblState.anchor = GridBagConstraints.EAST;
gbc_lblState.insets = new Insets(0, 0, 0, 5);
gbc_lblState.gridx = 4;
gbc_lblState.gridy = 2;
add(lblState, gbc_lblState);
textField_2 = new JTextField();
textField_2.setName("zip");
GridBagConstraints gbc_textField_2 = new GridBagConstraints();
gbc_textField_2.fill = GridBagConstraints.HORIZONTAL;
gbc_textField_2.gridx = 5;
gbc_textField_2.gridy = 2;
add(textField_2, gbc_textField_2);
textField_2.setColumns(10);
}
}
Corrected MyForm.java:
package gui_example_application;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JComboBox;
public class MyForm extends JPanel {
private JTextField firstName;
private JTextField lastName;
private JLabel lblStreet;
private JTextField textField;
private JLabel lblCity;
private JTextField textField_1;
private JLabel lblState;
private JComboBox comboBox;
private JLabel lblState_1;
private JTextField textField_2;
/**
* Create the panel.
*/
public MyForm() {
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{72, 134, 0, 0, 0, 0, 0};
gridBagLayout.rowHeights = new int[]{28, 28, 0, 0};
gridBagLayout.columnWeights = new double[]{0.0, 1.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
setLayout(gridBagLayout);
JLabel lblFirstName = new JLabel("First Name:");
GridBagConstraints gbc_lblFirstName = new GridBagConstraints();
gbc_lblFirstName.anchor = GridBagConstraints.WEST;
gbc_lblFirstName.insets = new Insets(0, 0, 5, 5);
gbc_lblFirstName.gridx = 0;
gbc_lblFirstName.gridy = 0;
add(lblFirstName, gbc_lblFirstName);
firstName = new JTextField();
firstName.setName("first-name");
firstName.setColumns(10);
GridBagConstraints gbc_firstName = new GridBagConstraints();
gbc_firstName.gridwidth = 2;
gbc_firstName.anchor = GridBagConstraints.NORTH;
gbc_firstName.fill = GridBagConstraints.HORIZONTAL;
gbc_firstName.insets = new Insets(0, 0, 5, 5);
gbc_firstName.gridx = 1;
gbc_firstName.gridy = 0;
add(firstName, gbc_firstName);
JLabel lblLastName = new JLabel("Last Name:");
GridBagConstraints gbc_lblLastName = new GridBagConstraints();
gbc_lblLastName.anchor = GridBagConstraints.WEST;
gbc_lblLastName.insets = new Insets(0, 0, 5, 5);
gbc_lblLastName.gridx = 3;
gbc_lblLastName.gridy = 0;
add(lblLastName, gbc_lblLastName);
lastName = new JTextField();
lastName.setName("last-name");
lastName.setColumns(10);
GridBagConstraints gbc_lastName = new GridBagConstraints();
gbc_lastName.gridwidth = 2;
gbc_lastName.fill = GridBagConstraints.HORIZONTAL;
gbc_lastName.insets = new Insets(0, 0, 5, 0);
gbc_lastName.anchor = GridBagConstraints.NORTH;
gbc_lastName.gridx = 4;
gbc_lastName.gridy = 0;
add(lastName, gbc_lastName);
lblStreet = new JLabel("Street:");
GridBagConstraints gbc_lblStreet = new GridBagConstraints();
gbc_lblStreet.anchor = GridBagConstraints.EAST;
gbc_lblStreet.insets = new Insets(0, 0, 5, 5);
gbc_lblStreet.gridx = 0;
gbc_lblStreet.gridy = 1;
add(lblStreet, gbc_lblStreet);
textField = new JTextField();
textField.setName("street");
GridBagConstraints gbc_textField = new GridBagConstraints();
gbc_textField.gridwidth = 5;
gbc_textField.insets = new Insets(0, 0, 5, 0);
gbc_textField.fill = GridBagConstraints.HORIZONTAL;
gbc_textField.gridx = 1;
gbc_textField.gridy = 1;
add(textField, gbc_textField);
textField.setColumns(10);
lblCity = new JLabel("City:");
GridBagConstraints gbc_lblCity = new GridBagConstraints();
gbc_lblCity.anchor = GridBagConstraints.EAST;
gbc_lblCity.insets = new Insets(0, 0, 0, 5);
gbc_lblCity.gridx = 0;
gbc_lblCity.gridy = 2;
add(lblCity, gbc_lblCity);
textField_1 = new JTextField();
textField_1.setName("city");
GridBagConstraints gbc_textField_1 = new GridBagConstraints();
gbc_textField_1.insets = new Insets(0, 0, 0, 5);
gbc_textField_1.fill = GridBagConstraints.HORIZONTAL;
gbc_textField_1.gridx = 1;
gbc_textField_1.gridy = 2;
add(textField_1, gbc_textField_1);
textField_1.setColumns(10);
lblState_1 = new JLabel("State:");
GridBagConstraints gbc_lblState_1 = new GridBagConstraints();
gbc_lblState_1.insets = new Insets(0, 0, 0, 5);
gbc_lblState_1.gridx = 2;
gbc_lblState_1.gridy = 2;
add(lblState_1, gbc_lblState_1);
comboBox = new JComboBox();
comboBox.setName("state");
GridBagConstraints gbc_comboBox = new GridBagConstraints();
gbc_comboBox.insets = new Insets(0, 0, 0, 5);
gbc_comboBox.fill = GridBagConstraints.HORIZONTAL;
gbc_comboBox.gridx = 3;
gbc_comboBox.gridy = 2;
add(comboBox, gbc_comboBox);
lblState = new JLabel("Zip:");
GridBagConstraints gbc_lblState = new GridBagConstraints();
gbc_lblState.anchor = GridBagConstraints.EAST;
gbc_lblState.insets = new Insets(0, 0, 0, 5);
gbc_lblState.gridx = 4;
gbc_lblState.gridy = 2;
add(lblState, gbc_lblState);
textField_2 = new JTextField();
textField_2.setName("zip");
GridBagConstraints gbc_textField_2 = new GridBagConstraints();
gbc_textField_2.fill = GridBagConstraints.HORIZONTAL;
gbc_textField_2.gridx = 5;
gbc_textField_2.gridy = 2;
add(textField_2, gbc_textField_2);
textField_2.setColumns(10);
}
}

you likely also need to rename the window_builder directory to match the change in name. and change the package names in any java files.
this is in keeping with the project naming pattern in Clojure of directory_name/namespace.clj with -'s switched to _'s

Related

QStandardItem redefinition error

I am trying to make a model using QStandardItemModel in Qt. I have done it in the following two ways. In the second method I just expanded the loop, and I get redefinition of 'item' error, while the first method works fine.
method 1
QStandardItemModel * model = new QStandardItemModel( 3, 1 );
QStringList modelStepsTags = {"item-1","item-2","item-3"};
for( int r=0; r<3; r=r+1 )
{
QStandardItem *item = new QStandardItem( modelStepsTags.at(r) );
model->setItem(r, 0, item);
}
method 2
QStandardItemModel * model = new QStandardItemModel( 3, 1 );
QStringList modelStepsTags = {"item-1","item-2","item-3"};
QStandardItem *item = new QStandardItem( modelStepsTags.at(0) );
model->setItem(0, 0, item);
QStandardItem *item = new QStandardItem( modelStepsTags.at(1) );
model->setItem(1, 0, item);
QStandardItem *item = new QStandardItem( modelStepsTags.at(2) );
model->setItem(2, 0, item);
Item is defined three times.
QStandardItemModel * model = new QStandardItemModel( 3, 1 );
QStringList modelStepsTags = {"item-1","item-2","item-3"};
QStandardItem *item = new QStandardItem( modelStepsTags.at(0) ); // here
model->setItem(0, 0, item);
QStandardItem *item = new QStandardItem( modelStepsTags.at(1) ); // here
model->setItem(1, 0, item);
QStandardItem *item = new QStandardItem( modelStepsTags.at(2) ); // and here
model->setItem(2, 0, item);
You can get away with reusing the first definition
QStandardItemModel * model = new QStandardItemModel( 3, 1 );
QStringList modelStepsTags = {"item-1","item-2","item-3"};
QStandardItem *item = new QStandardItem( modelStepsTags.at(0) );
model->setItem(0, 0, item);
item = new QStandardItem( modelStepsTags.at(1) ); // reuse
model->setItem(1, 0, item);
item = new QStandardItem( modelStepsTags.at(2) ); // reuse
model->setItem(2, 0, item);
Or discard the variable entirely as it is redundant
QStandardItemModel * model = new QStandardItemModel( 3, 1 );
QStringList modelStepsTags = {"item-1","item-2","item-3"};
model->setItem(0, 0, new QStandardItem( modelStepsTags.at(0) ));
model->setItem(1, 0, new QStandardItem( modelStepsTags.at(1) ));
model->setItem(2, 0, new QStandardItem( modelStepsTags.at(2) ));

How to fill QCameraViewFinder with background color?

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_QPushButton_calibration = new QPushButton("Calibrate", this);
connect(m_QPushButton_calibration, SIGNAL (released()),this, SLOT (handleButton()));
QList<QCameraInfo> l_QListQCameraInfo_available_cameras = QCameraInfo::availableCameras();
m_QCameraViewfinder_viewfinder = new QCameraViewfinder(this);
if (l_QListQCameraInfo_available_cameras.length() >= 2)
{
m_QCamera_required_camera = new QCamera (l_QListQCameraInfo_available_cameras[1]);
m_QCamera_required_camera->setViewfinder(m_QCameraViewfinder_viewfinder);
m_QCamera_required_camera->start ();
}
m_QWidget_central = new QWidget;
m_QGridLayout_main_screen = new QGridLayout;
m_QWidget_central->setStyleSheet ("background-color: green");
m_QWidget_central->setLayout (m_QGridLayout_main_screen);
m_QPushButton_calibration->setStyleSheet ("background-color: pink");
m_QGridLayout_main_screen->addWidget (m_QPushButton_calibration, 0, 0, 1, 1);
m_QCameraViewfinder_viewfinder->setStyleSheet ("background-color: blue");
m_QGridLayout_main_screen->addWidget (m_QCameraViewfinder_viewfinder, 1, 1, 2, 1);
this->setCentralWidget (m_QWidget_central);
m_QCameraViewfinder_viewfinder->show();
}
I have tried this: m_QCameraViewfinder_viewfinder->setStyleSheet ("background-color: blue");
Didn't help.
No camera attached as of now. How to fill QCameraViewFinder with background color?
Output is here:

How to use vtkImplicitPlaneWidget2 in Qt

I have trouble while combining Qt with vtkImplicitPlaneWidget2 then.
Without Qt, I could have the result shown like this.
Without Qt
But with Qt, I could not display the basic function of vtkImplicitPlaneWidget2, or in other words, it only shows the volume data, but the clipper of the plane could not be shown, just like the picture below.
With Qt
I try to find the result, and it seems that the callback function is never called in Qt. I think it is because that I don't connect the Qt event to the callback function, but I don't know how to deal with this.
And the following is the code.
void planeWidgetPara::showLabelPlane()
{
this->setupUi(this);
#pragma region image_process
vtkSmartPointer<vtkImageData> imageData =
vtkSmartPointer<vtkImageData>::New();
imageData->SetExtent(0, dims[0] / scaledown - 1,
0, dims[1] / scaledown - 1,
0, dims[2]);
imageData->SetSpacing(this->getSpacing());
imageData->AllocateScalars(VTK_UNSIGNED_CHAR, 3);
int scaledown = this->getScaledown();
for (int i = 0;i < dims[0] / scaledown;i++)
{
for (int j = 0;j < dims[1] / scaledown;j++)
{
for (int k = 0;k < dims[2];k++)
{
imageData->SetScalarComponentFromDouble(i, j, k, 0, getLabelScaledownColor(i, j, k, 0, scaledown));
imageData->SetScalarComponentFromDouble(i, j, k, 1, getLabelScaledownColor(i, j, k, 1, scaledown));
imageData->SetScalarComponentFromDouble(i, j, k, 2, getLabelScaledownColor(i, j, k, 2, scaledown));
}
}
}
vtkSmartPointer<vtkImageDataGeometryFilter> imageDataGeometryFilter =
vtkSmartPointer<vtkImageDataGeometryFilter>::New();
imageDataGeometryFilter->SetInputData(imageData);
imageDataGeometryFilter->Update();
// Setup a visualization pipeline
vtkSmartPointer<vtkPlane> plane =
vtkSmartPointer<vtkPlane>::New();
plane->SetOrigin(this->getRawOrigin());
vtkSmartPointer<vtkClipPolyData> clipper =
vtkSmartPointer<vtkClipPolyData>::New();
clipper->SetClipFunction(plane);
clipper->InsideOutOn();
clipper->SetInputConnection(imageDataGeometryFilter->GetOutputPort());
// Create a mapper and actor
vtkSmartPointer<vtkPolyDataMapper> mapper =
vtkSmartPointer<vtkPolyDataMapper>::New();
mapper->SetInputConnection(clipper->GetOutputPort());
vtkSmartPointer<vtkActor> actor =
vtkSmartPointer<vtkActor>::New();
actor->SetMapper(mapper);
vtkSmartPointer<vtkProperty> backFaces =
vtkSmartPointer<vtkProperty>::New();
backFaces->SetDiffuseColor(.8, .8, .4);
actor->SetBackfaceProperty(backFaces);
#pragma endregion
// A renderer and render window
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =
this->qvtkWidget->GetRenderWindow();
renderWindow->AddRenderer(renderer);
renderer->AddActor(actor);
//// An interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
this->qvtkWidget->GetRenderWindow()->GetInteractor();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
// The callback will do the work
vtkSmartPointer<vtkIPWCallback> myCallback =
vtkSmartPointer<vtkIPWCallback>::New();
myCallback->Plane = plane;
myCallback->Actor = actor;
vtkSmartPointer<vtkImplicitPlaneRepresentation> rep =
vtkSmartPointer<vtkImplicitPlaneRepresentation>::New();
rep->SetPlaceFactor(1.25); // This must be set prior to placing the widget
rep->PlaceWidget(actor->GetBounds());
rep->SetNormal(plane->GetNormal());
vtkSmartPointer<vtkImplicitPlaneWidget2> planeWidget =
vtkSmartPointer<vtkImplicitPlaneWidget2>::New();
planeWidget->SetInteractor(renderWindowInteractor);
planeWidget->SetRepresentation(rep);
planeWidget->AddObserver(vtkCommand::InteractionEvent, myCallback);
// Render
renderWindowInteractor->Initialize();
renderWindow->Render();
planeWidget->On();
// Begin mouse interaction
//renderWindowInteractor->Start();
// VTK/Qt wedded
this->qvtkWidget->GetRenderWindow()->AddRenderer(renderer);
// Set up action signals and slots
connect(this->actionExit, SIGNAL(triggered()), this, SLOT(slotExit()));
}

Layout of progress bars with different horizontal positions

I want to have a dynamic list of QProgessBars laid out vertically. But the thing is I want some of them to be moved horizontally. For example:
#################
###########
###########
######
When I move widgets in the layout like this:
sl->move(10, 0);
nothing happens.
I also tried using QGridLayout with spacers:
QGridLayout * lay = new QGridLayout();
lay->setAlignment(Qt::AlignLeft|Qt::AlignTop);
for (int i = 1; i < 15; ++i) {
QProgressBar * sl = new QProgressBar();
QSpacerItem * sp = new QSpacerItem(10, 10 + i);
lay->addWidget(sl, i, 0);
lay->addItem(sp, i, 0);
}
I there a way to do it programmatically?
Hi you need to use this QGridLayout::addWidget version. For instance, when you execute
grid->addWidget(w1, 0, 0, 1, 5);
grid->addWidget(w2, 1, 1, 2, 3);
grid->addWidget(w3, 3, 0, 1, 5);
your final gui will look something like this:
w1 w1 w1 w1 w1
w2 w2 w2
w2 w2 w2
w3 w3 w3 w3 w3
You can see the grid as a 2D-array. So w2 starts from grid[1][1] and spans over 2 rows and 3 columns. And since w2 spans over 2 rows, w3 should start at w1's row + 2 (i.e. 3).
Do layout nesting, like they would do in html. Vertical layout with four (or three, if first row got only progress bar) horizontal layouts in it
But using Grid as top layout would allow to add margins at sides.
Of course you can do that programmatically. I've shown how that may look in Designer, but what designer actually does is to generate plain linear code. You can do that in for cycle instead.
Generated code:
if (Dialog->objectName().isEmpty())
Dialog->setObjectName(QString::fromUtf8("Dialog"));
Dialog->resize(504, 377);
gridLayoutWidget = new QWidget(Dialog);
gridLayoutWidget->setObjectName(QString::fromUtf8("gridLayoutWidget"));
gridLayoutWidget->setGeometry(QRect(9, 9, 481, 351));
gridLayout = new QGridLayout(gridLayoutWidget);
gridLayout->setObjectName(QString::fromUtf8("gridLayout"));
gridLayout->setContentsMargins(0, 0, 0, 0);
horizontalLayout_3 = new QHBoxLayout();
horizontalLayout_3->setObjectName(QString::fromUtf8("horizontalLayout_3"));
horizontalSpacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_3->addItem(horizontalSpacer);
progressBar_2 = new QProgressBar(gridLayoutWidget);
progressBar_2->setObjectName(QString::fromUtf8("progressBar_2"));
progressBar_2->setValue(24);
horizontalLayout_3->addWidget(progressBar_2);
horizontalSpacer_2 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_3->addItem(horizontalSpacer_2);
gridLayout->addLayout(horizontalLayout_3, 1, 0, 1, 1);
horizontalLayout_2 = new QHBoxLayout();
horizontalLayout_2->setObjectName(QString::fromUtf8("horizontalLayout_2"));
horizontalSpacer_3 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout_2->addItem(horizontalSpacer_3);
progressBar_3 = new QProgressBar(gridLayoutWidget);
progressBar_3->setObjectName(QString::fromUtf8("progressBar_3"));
progressBar_3->setValue(24);
horizontalLayout_2->addWidget(progressBar_3);
gridLayout->addLayout(horizontalLayout_2, 2, 0, 1, 1);
horizontalLayout = new QHBoxLayout();
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
progressBar_4 = new QProgressBar(gridLayoutWidget);
progressBar_4->setObjectName(QString::fromUtf8("progressBar_4"));
progressBar_4->setValue(24);
horizontalLayout->addWidget(progressBar_4);
horizontalSpacer_4 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum);
horizontalLayout->addItem(horizontalSpacer_4);
gridLayout->addLayout(horizontalLayout, 3, 0, 1, 1);
horizontalLayout_4 = new QHBoxLayout();
horizontalLayout_4->setObjectName(QString::fromUtf8("horizontalLayout_4"));
progressBar = new QProgressBar(gridLayoutWidget);
progressBar->setObjectName(QString::fromUtf8("progressBar"));
progressBar->setValue(24);
horizontalLayout_4->addWidget(progressBar);
gridLayout->addLayout(horizontalLayout_4, 0, 0, 1, 1);

Why the layout managers in QT doesn't work?

this->setWindowTitle(tr("数据转移程序"));
edt_ftp_server = new QLineEdit;
edt_ftp_port = new QLineEdit;
edt_ftp_account = new QLineEdit;
edt_ftp_pwd = new QLineEdit;
edt_ftp_pwd->setEchoMode( QLineEdit::Password );
lbl_ftp_server = new QLabel;
lbl_ftp_server->setText(tr("FTP服务器地址:"));
lbl_ftp_server->setBuddy( edt_ftp_server );
lbl_ftp_port = new QLabel;
lbl_ftp_port->setText(tr("FTP服务器端口:"));
lbl_ftp_port->setBuddy( edt_ftp_port );
lbl_ftp_account = new QLabel;
lbl_ftp_account->setText(tr("FTP登录帐号:"));
lbl_ftp_account->setBuddy( edt_ftp_account );
lbl_ftp_pwd = new QLabel;
lbl_ftp_pwd->setText(tr("FTP登录密码:"));
lbl_ftp_pwd->setBuddy( edt_ftp_pwd );
ftp_settings = new QGroupBox(this);
ftp_settings->setTitle(tr("FTP服务器设置"));
ftp_settingsLayout = new QGridLayout;
ftp_settingsLayout->addWidget( lbl_ftp_server, 0, 0);
ftp_settingsLayout->addWidget( edt_ftp_server, 0, 1);
ftp_settingsLayout->addWidget( lbl_ftp_port, 1, 0);
ftp_settingsLayout->addWidget( edt_ftp_port, 1, 1);
ftp_settingsLayout->addWidget( lbl_ftp_account, 2, 0);
ftp_settingsLayout->addWidget( edt_ftp_account, 2, 1);
ftp_settingsLayout->addWidget( lbl_ftp_pwd, 3, 0);
ftp_settingsLayout->addWidget( edt_ftp_pwd, 3, 1);
ftp_settings->setLayout( ftp_settingsLayout );
edt_db_server = new QLineEdit( this );
edt_db_port = new QLineEdit( this );
edt_db_account = new QLineEdit( this );
edt_db_pwd = new QLineEdit( this );
edt_db_pwd->setEchoMode( QLineEdit::Password );
lbl_db_server = new QLabel( this );
lbl_db_server->setText(tr("FTP服务器地址:"));
lbl_db_server->setBuddy( edt_ftp_server );
lbl_db_port = new QLabel( this );
lbl_db_port->setText(tr("FTP服务器端口:"));
lbl_db_port->setBuddy( edt_ftp_port );
lbl_db_account = new QLabel( this );
lbl_db_account->setText(tr("FTP登录帐号:"));
lbl_db_account->setBuddy( edt_ftp_account );
lbl_db_pwd = new QLabel( this );
lbl_db_pwd->setText(tr("FTP登录密码"));
lbl_db_pwd->setBuddy( edt_ftp_pwd );
db_settings = new QGroupBox(this);
db_settings->setTitle(tr("数据库服务器设置"));
db_settingsLayout = new QGridLayout;
db_settingsLayout->addWidget( lbl_ftp_server, 0, 0);
db_settingsLayout->addWidget( edt_ftp_server, 0, 1);
db_settingsLayout->addWidget( lbl_ftp_port,1, 0);
db_settingsLayout->addWidget( edt_ftp_port,1, 1);
db_settingsLayout->addWidget( lbl_ftp_account, 2, 0);
db_settingsLayout->addWidget( edt_ftp_account, 2, 1);
db_settingsLayout->addWidget( lbl_ftp_pwd,3, 0);
db_settingsLayout->addWidget( edt_ftp_pwd, 3, 1);
db_settings->setLayout( db_settingsLayout );
buttonsLayout = new QHBoxLayout;
buttonsLayout->addStretch();
btn_start = new QPushButton;
btn_start->setText(tr("开始"));
buttonsLayout->addWidget(btn_start);
btn_stop = new QPushButton;
btn_stop->setText(tr("停止"));
buttonsLayout->addWidget( btn_stop );
btn_exit = new QPushButton;
btn_exit->setText(tr("退出"));
buttonsLayout->addWidget(btn_exit);
settingLayout = new QVBoxLayout;
settingLayout->addWidget( db_settings );
settingLayout->addStretch();
settingLayout->addWidget( ftp_settings );
centralLayout = new QHBoxLayout;
centralLayout->addLayout( settingLayout );
lst_log = new QListWidget;
centralLayout->addWidget(lst_log);
winLayout = new QVBoxLayout;
winLayout->addLayout( centralLayout );
winLayout->addLayout( buttonsLayout );
setLayout( winLayout );
I am developing a tiny qt program, and have writen above code in a QMainWindow subclass Constructor.
But the widgets displayed are messed up.All advices are appreciated!
The following is the result screenshot:
I suspect that the problem lies in the top level layout, which is winLayout. Set QMainWindow's central widget to winLayout's parent:
winLayout = new QVBoxLayout(ui->centralWidget);
I recommend using Qt Creator or Qt Designer for designing the user interfaces. Qt Creator creates the necessary code for layouts and other uninteresting things. And even if you decide to create user interfaces by writing your own code, you can create a prototype with Qt Creator and look what kind of code it creates.