Why the layout managers in QT doesn't work? - c++

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.

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) ));

wxWidgets C++ panel is invisible

I am starting to practise my skills with wxWidgets and I wanted to add some panel with two different texts above this slider, but when I tried, the result is invisible:
MainWindow::MainWindow(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition) {
wxMenuBar *menubar;
wxMenu *file;
menubar = new wxMenuBar;
file = new wxMenu;
file->Append(wxID_OPEN, wxT("&Open"));
menubar->Append(file, wxT("&File"));
SetMenuBar(menubar);
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
this->SetSizer(vbox);
player_widget = new wxWindow(this, wxID_ANY);
player_widget->SetBackgroundColour(wxColour(wxT("black")));
vbox->Add(player_widget, 1, wxEXPAND | wxALIGN_TOP);
wxBoxSizer* bs = new wxBoxSizer(wxHORIZONTAL);
wxPanel* p1 = new wxPanel(this,wxID_ANY,wxDefaultPosition,wxSize(0,20));
p1->SetSizer(bs);
p1->Enable(true);
p1->Show(true);
vbox->Add(p1,0,wxEXPAND);
wxStaticText* text1 = new wxStaticText(this,11, "text 1");
wxStaticText* text2 = new wxStaticText(this,12, "text 2");
bs->Add(text1);
bs->Add(text2);
timeline = new wxSlider(this, myID_TIMELINE, 0, 0, TIMELINE_MAX);
vbox->Add(timeline, 0, wxEXPAND);
wxPanel *controlPanel = new wxPanel(this, wxID_ANY);
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
controlPanel->SetSizer(hbox);
vbox->Add(controlPanel, 0, wxEXPAND);
playpause_button = new wxButton(controlPanel, myID_PLAYPAUSE, wxT("Play"));
stop_button = new wxButton(controlPanel, myID_STOP, wxT("Stop"));
volume_slider = new wxSlider(controlPanel, myID_VOLUME, VOLUME_MAX, 0, VOLUME_MAX, wxDefaultPosition, wxSize(100, -1));
hbox->Add(playpause_button);
hbox->Add(stop_button);
hbox->AddStretchSpacer();
hbox->Add(volume_slider);
}
Any ideas what I did wrong?
Change parent of text1 and text2 to p1.
It is simpler to use just one panel that holds everything.
Something like this ( a complete program )
#include <wx/wx.h>
#include <wx/app.h>
class cApp : public wxApp
{
public:
virtual bool OnInit();
};
#define TIMELINE_MAX 100
#define VOLUME_MAX 100
enum {
myID_TIMELINE,
myID_PLAYPAUSE,
myID_STOP,
myID_VOLUME
};
class cFrame: public wxFrame
{
wxWindow * player_widget;
wxSlider * timeline;
wxSlider * volume_slider;
wxButton * playpause_button;
wxButton * stop_button;
public:
cFrame(wxFrame *frame, const wxString& title)
: wxFrame(frame, -1, title, wxPoint(-1,-1),wxSize(600,600))
{
wxMenuBar *menubar;
wxMenu *file;
menubar = new wxMenuBar;
file = new wxMenu;
file->Append(wxID_OPEN, wxT("&Open"));
menubar->Append(file, wxT("&File"));
SetMenuBar(menubar);
// define one panel to hold everything
// make it big enough to fill the frame
wxPanel* p1 = new wxPanel(this,wxID_ANY, wxPoint(-1,-1),wxSize(600,600) );
// top level sizer to hold everything
wxBoxSizer *vbox = new wxBoxSizer(wxVERTICAL);
// add window widget at top
player_widget = new wxWindow(p1, wxID_ANY);
player_widget->SetBackgroundColour(wxColour(wxT("black")));
vbox->Add(player_widget, 1, wxEXPAND | wxALIGN_TOP);
// add some texts in a horizontal row
wxBoxSizer* bs = new wxBoxSizer(wxHORIZONTAL);
wxStaticText* text1 = new wxStaticText(p1,11, "text 1");
wxStaticText* text2 = new wxStaticText(p1,12, "text 2");
bs->Add(text1);
bs->Add(text2);
// add texts just below window widget
vbox->Add( bs );
// add slider below texts
timeline = new wxSlider(this, myID_TIMELINE, 0, 0, TIMELINE_MAX);
vbox->Add(timeline, 0, wxEXPAND);
// some more controls in a row
wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
playpause_button = new wxButton(p1, myID_PLAYPAUSE, wxT("Play"));
stop_button = new wxButton(p1, myID_STOP, wxT("Stop"));
volume_slider = new wxSlider(p1, myID_VOLUME, VOLUME_MAX,
0, VOLUME_MAX, wxDefaultPosition, wxSize(100, -1));
hbox->Add(playpause_button);
hbox->Add(stop_button);
hbox->AddStretchSpacer();
hbox->Add(volume_slider);
// add controls below big slider
vbox->Add( hbox );
// make everything happen
SetSizer(vbox);
}
};
IMPLEMENT_APP(cApp);
bool cApp::OnInit()
{
cFrame* frame = new cFrame(0L, _("wx Starter"));
frame->Show();
return true;
}
This gives:
Here's the thing about computer programming: at some time you always have to settle down and write some code. All those applications, like wxFormBuilder, that promise to write code for you have to be abandoned at some point and you actually have to do some work ( Here is a link to more about this )

QObject::connect: No such slot QWidget::makeyourbox() in occQt.cpp:324

I am new to here.
The ui run well ,but when I click 'okbtn' ...
QObject::connect: No such slot QWidget::makeyourbox() in occQt.cpp:324
And when I click 'cancelbtn', it runs.
Thanks for any responses,
Eason
code:
void occQt::about2() //UI
{
QWidget* pWidget = new QWidget;
QLabel* longlabel = new QLabel(tr("long"));
QLabel* widthlabel = new QLabel(tr("width"));
QLabel* highlabel = new QLabel(tr("high"));
longlineedit = new QLineEdit;
widthlineedit = new QLineEdit;
highlineedit = new QLineEdit;
QPushButton* okbtn = new QPushButton(tr("ok"));
QPushButton* cancelbtn = new QPushButton(tr("cancel"));
QGridLayout* gridlayout = new QGridLayout;
QVBoxLayout* dlglayout = new QVBoxLayout;
QHBoxLayout* btnlayout = new QHBoxLayout;
gridlayout->addWidget(longlabel, 0, 0, 1, 1);
gridlayout->addWidget(widthlabel, 1, 0, 1, 1);
gridlayout->addWidget(highlabel, 2, 0, 1, 1);
gridlayout->addWidget(longlineedit, 0, 1, 1, 3);
gridlayout->addWidget(widthlineedit, 1, 1, 1, 3);
gridlayout->addWidget(highlineedit, 2, 1, 1, 3);
longlineedit->setText("5");
widthlineedit->setText("5");
highlineedit->setText("5");
btnlayout->setSpacing(60);
btnlayout->addWidget(okbtn);
btnlayout->addWidget(cancelbtn);
//pWidget->setLayout(gridlayout);
dlglayout->setMargin(50);
dlglayout->addLayout(gridlayout);
dlglayout->addStretch(40);
dlglayout->addLayout(btnlayout);
pWidget->setLayout(dlglayout);
pWidget->setWindowTitle(tr("Make a Box by custom."));
pWidget->show();
connect(okbtn, SIGNAL(clicked()), pWidget, SLOT(makeyourbox()));
//QObject::connect(okbtn, SIGNAL(clicked()), pWidget, SLOT(close()));
connect(cancelbtn, SIGNAL(clicked()), pWidget, SLOT(close()));
}
void occQt::makeyourbox()
{
QString string_a = longlineedit->text();
eason_a = string_a.toInt();
QString string_b = widthlineedit->text();
eason_b = string_b.toInt();
QString string_c = highlineedit->text();
eason_c = string_c.toInt();
TopoDS_Shape aTopoBox = BRepPrimAPI_MakeBox(eason_a, eason_b, eason_c).Shape();
Handle_AIS_Shape anAisBox = new AIS_Shape(aTopoBox);
anAisBox->SetColor(Quantity_NOC_AZURE);
mContext->Display(anAisBox);
}
When I run the pWidget, click cancelbtn, ui close.
Click okbtn,do nothing..
pWidget is a generic QWidget. It does not contain method/slot makeyourbox().
Your code is faulty.
you should add makeyourbox() method to the subclass of QWidget, and mark it as slot
Double check makeyourbox is defined to be a slot within that class.

Why does widget.resize() not work?

My C++ code(use opencv and qt):
face_detect::face_detect(QWidget *parent)
: QWidget(parent)
{
imgwidget = new showwidget("D:\\sample.avi");
imgwidget->resize(QSize(640,480));
setWindowTitle(tr("Face Detection!"));
FaceNumLabel = new QLabel(tr("face_num: "));
num = new QLabel;
num->setFrameStyle(QFrame::Panel | QFrame::Sunken);
ImgSource = new QLabel(tr("image source: "));
VedioBtn = new QPushButton(tr("from vedio"));
LocalImgBtn = new QPushButton(tr("local image"));
LeftLayout = new QVBoxLayout();
LeftLayout->addWidget(imgwidget);
LeftLayout->addWidget(FaceNumLabel);
LeftLayout->addWidget(num);
//LeftLayout->addWidget(ShowImageLabel, 3, 0, 1, 2);
RightLayout = new QVBoxLayout();
RightLayout->addWidget(ImgSource);
RightLayout->addWidget(VedioBtn);
RightLayout->addWidget(LocalImgBtn);
RightLayout->addWidget(ImgSource);
QHBoxLayout *mainLayout = new QHBoxLayout(this);
mainLayout->addLayout(LeftLayout);
mainLayout->addLayout(RightLayout);
mainLayout->setSizeConstraint(QLayout::SetFixedSize);
connect(VedioBtn, SIGNAL(clicked()), this, SLOT(openvedio()));
connect(LocalImgBtn, SIGNAL(clicked()), this, SLOT(localimg()));
}
I call widget.resize() to resize the widget, and then add it to the layout. But when I run the program, the showimgwidget's is not 640*480. Why is that?

Displaying an image with QGraphics Scene

Having an issue with displaying a loaded image in a QGraphicsScene.
CTextBox::CTextBox(QWidget* parent /* = NULL */)
{
QPixmap image;
image.load("basketball.png");
grid = new QGridLayout();
grid->setSpacing(1);
textBrowser = new QTextEdit(this);
treeView = new QTreeView;
treeLabel = new QLabel;
treeLabel->setText("Tree View:");
debugLabel = new QLabel;
debugLabel->setText("Debug:");
standardModel = new QStandardItemModel;
rootNode = standardModel->invisibleRootItem();
treeView->setModel(standardModel);
QGraphicsPixmapItem pixmapitem(image);
//scene.addText("Graphics");
scene.addItem(&pixmapitem);
//rect = scene.addRect(QRectF(0,0, 100, 100));
//QGraphicsItem *item = scene.itemAt(50, 50);
widget = new QWidget();
view = new QGraphicsView;
view->setScene(&scene);
view->setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers)));
//proxy = scene.addWidget(widget);
//label = new QLabel();
grid->addWidget(textBrowser, 1, 0);
grid->addWidget(debugLabel, 0, 0);
grid->addWidget(treeView, 1, 1);
grid->addWidget(treeLabel, 0, 1);
//grid->addWidget(&image, 2,0);
//grid->addWidget(view, 2, 0);
//grid->addWidget(widget, 2, 0);
//grid->addWidget(proxy, 2,0);
view->show();
//widget->setLayout(view);
//widget->show();
setLayout(grid);
//label->addItem()
}
Basically when I try and load the image in a QGraphicsScene it seems to scale up to the size of the image but displays a white screen. I can add text to the graphics scene fine and that will display correctly. Now if I try to do add the image into a label on a different widget it displays fine. Any ideas why?
Cheers.
You don't see it because you pass a reference to a local object of the constructor. The pixmap item will be destructed immediately after your constructor ends. Use dynamic allocation instead.
QGraphicsPixmapItem* pixmapitem = new QGraphicsPixmapItem(image);
scene.addItem(pixmapitem);