Recently updated from qt 5.8 to qt 5.9 and I'm getting some problems.
Pressing on a button that is not connected to any slot gives me:
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Which is quite odd because before the update, it worked flawlessly. I'll paste some parts of the code so it will be a bit more clear.
First of all GUI is a class that inherits from QWidget.
#ifndef GUI_H
#define GUI_H
#include <QWidget>
#include <QHBoxLayout>
#include <QPushButton>
#include <QVBoxLayout>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include "Controller.h"
class GUI : public QWidget
{
Q_OBJECT
public:
GUI(Controller* ctrl);
void start();
~GUI();
private:
QLineEdit* txt_title;
QLineEdit* txt_desc;
QLineEdit* txt_type;
QLineEdit* txt_dur;
QPushButton* add_btn;
QPushButton* upd_btn;
QPushButton* rm_btn;
QPushButton* fil_desc_btn;
QPushButton* fil_type_btn;
QPushButton* fil_search_btn;
QPushButton* sort_title_btn;
QPushButton* sort_desc_btn;
QPushButton* sort_type_btn;
QPushButton* undo_btn;
QPushButton* refresh_btn;
QPushButton* shuffle_btn;
QListWidget* activities;
Controller* ctrl;
void setup_gui();
void connect_gui();
void add_to_list(Activity&);
void update_list();
public slots:
void add();
void edit();
void remove();
void search();
void undo();
void refresh_list();
void sort_title();
void sort_desc();
void sort_type();
void filter_desc();
void filter_type();
void shuffle();
};
#endif
And the methods that are relevant:
GUI::GUI(Controller* _ctrl)
{
this->ctrl = _ctrl;
this->setup_gui();
this->connect_gui();
setAttribute(Qt::WA_DeleteOnClose);
}
void GUI::add_to_list(Activity& activity)
{
string str = "";
str += activity.get_title() + "; " + activity.get_description() + "; " + activity.get_type() + "; " + std::to_string(activity.get_duration());
new QListWidgetItem(QString::fromStdString(str), this->activities);
}
void GUI::setup_gui()
{
this->setContentsMargins(10, 10, 10, 10);
QHBoxLayout* main_lay = new QHBoxLayout(this);
QVBoxLayout* left_lay = new QVBoxLayout();
QVBoxLayout* right_lay = new QVBoxLayout();
QHBoxLayout* title_lay = new QHBoxLayout();
QLabel* lbl_title = new QLabel(QObject::tr("title"));
lbl_title->setAlignment(Qt::AlignCenter);
this->txt_title = new QLineEdit();
QHBoxLayout* desc_lay = new QHBoxLayout();
QLabel* lbl_desc = new QLabel(QObject::tr("description"));
lbl_desc->setAlignment(Qt::AlignCenter);
this->txt_desc = new QLineEdit();
QHBoxLayout* type_lay = new QHBoxLayout();
QLabel* lbl_type = new QLabel(QObject::tr("type"));
lbl_type->setAlignment(Qt::AlignCenter);
this->txt_type = new QLineEdit();
QHBoxLayout* dur_lay = new QHBoxLayout();
QLabel* lbl_dur = new QLabel(QObject::tr("duration"));
lbl_dur->setAlignment(Qt::AlignCenter);
this->txt_dur = new QLineEdit();
QHBoxLayout* op_lay = new QHBoxLayout();
this->add_btn = new QPushButton(QObject::tr("&Add"));
this->upd_btn = new QPushButton(QObject::tr("Updat&e"));
this->rm_btn = new QPushButton(QObject::tr("&Remove"));
QHBoxLayout* fil_lay = new QHBoxLayout();
this->fil_desc_btn = new QPushButton(QObject::tr("FilterBy&Desc"));
this->fil_type_btn = new QPushButton(QObject::tr("FilterBy&Type"));
this->fil_search_btn = new QPushButton(QObject::tr("&Search"));
QHBoxLayout* undo_lay = new QHBoxLayout();
this->undo_btn = new QPushButton(QObject::tr("U&ndo"));
this->shuffle_btn = new QPushButton(QObject::tr("S&huffle"));
this->refresh_btn = new QPushButton(QObject::tr("Re&fresh"));
this->activities = new QListWidget();
main_lay->addLayout(left_lay);
main_lay->addLayout(right_lay);
title_lay->addWidget(lbl_title);
title_lay->addStretch();
title_lay->addWidget(txt_title);
desc_lay->addWidget(lbl_desc);
desc_lay->addStretch();
desc_lay->addWidget(txt_desc);
type_lay->addWidget(lbl_type);
type_lay->addStretch();
type_lay->addWidget(txt_type);
dur_lay->addWidget(lbl_dur);
dur_lay->addStretch();
dur_lay->addWidget(txt_dur);
op_lay->addWidget(add_btn);
op_lay->addWidget(upd_btn);
op_lay->addWidget(rm_btn);
fil_lay->addWidget(fil_desc_btn);
fil_lay->addWidget(fil_type_btn);
fil_lay->addWidget(fil_search_btn);
undo_lay->addWidget(refresh_btn);
undo_lay->addWidget(shuffle_btn);
undo_lay->addWidget(undo_btn);
right_lay->addLayout(title_lay);
right_lay->addLayout(desc_lay);
right_lay->addLayout(type_lay);
right_lay->addLayout(dur_lay);
right_lay->addLayout(op_lay);
right_lay->addLayout(fil_lay);
right_lay->addLayout(undo_lay);
QHBoxLayout* sort_lay = new QHBoxLayout();
this->sort_title_btn = new QPushButton(QObject::tr("SortByTit&le"));
this->sort_desc_btn = new QPushButton(QObject::tr("SortByDes&c"));
this->sort_type_btn = new QPushButton(QObject::tr("SortByT&ype"));
left_lay->addWidget(activities);
left_lay->addLayout(sort_lay);
sort_lay->addWidget(sort_title_btn);
sort_lay->addWidget(sort_desc_btn);
sort_lay->addWidget(sort_type_btn);
this->refresh_list();
}
void GUI::connect_gui()
{
QObject::connect(add_btn, SIGNAL(clicked()), this, SLOT(add()));
QObject::connect(upd_btn, SIGNAL(clicked()), this, SLOT(edit()));
QObject::connect(rm_btn, SIGNAL(clicked()), this, SLOT(remove()));
QObject::connect(sort_title_btn, SIGNAL(clicked()), this, SLOT(search()));
QObject::connect(undo_btn, SIGNAL(clicked()), this, SLOT(undo()));
QObject::connect(refresh_btn, SIGNAL(clicked()), this, SLOT(refresh_list()));
QObject::connect(fil_search_btn, SIGNAL(clicked()), this, SLOT(search()));
// QObject::connect(sort_title_btn, SIGNAL(clicked()), this, SLOT(sort_title()));
QObject::connect(sort_type_btn, SIGNAL(clicked()), this, SLOT(sort_type()));
QObject::connect(sort_desc_btn, SIGNAL(clicked()), this, SLOT(sort_desc()));
QObject::connect(shuffle_btn, SIGNAL(clicked()), this, SLOT(shuffle()));
QObject::connect(fil_desc_btn, SIGNAL(clicked()), this, SLOT(filter_desc()));
QObject::connect(fil_type_btn, SIGNAL(clicked()), this, SLOT(filter_type()));
}
Main problem is the button "sort_title_btn" which when connected to an empty method or not at all connected gives me the error when clicked.
The creation of the project was done by:
qmake -project
Editing the .pro file to add QT += core gui widgets and to include the folder with headers.
qmake
And finally: make
Compiles nicely, all buttons work except "sort_title_btn" even when NOT connected to a SLOT and "search" if the field by which the search has to be made is empty, that's not a problem for it can be fixed easily.
So, what is there to be done for the "sort_title_btn"?
I tried to put it to another SLOT, it works. Changing the name of the function I connect it to seems to bug out or something giving me the error.
Related
A program has the main window, the menu bar, the menu item (QAction in Qt), the tab widget, the text edit. I try to receive the sequenced numeration in the tabs when I press on the menu item (New Tab).
When I press on the New Tab then tab 1, tab 2, tab 3, tab 4 and so on must appear.
The suggested approximate code is here:
MainWindow::MainWindow(QWidget* parent):QMainWindow(parent)
{
QMenuBar* menuBar = new QMenuBar(this);
setMenuBar(menuBar);
QMenu* fileMenu = new QMenu("&File", this);
menuBar->addMenu(fileMenu);
QAction* newTabAction = new QAction("&New Tab", this);
fileMenu->addAction(newTabAction);
connect(newTabAction, SIGNAL(triggered()), this, SLOT(newTabActionHandler()));
QTabWidget* tabWidget = new QTabWidget(this);
QList<QWidget*> widgetList;
widgetList.append(new QWidget(this));
tabWidget->addTab(widgetList[0], "Tab 0");
tabWidget->setMovable(true);
tabWidget->setTabsClosable(true);
QList<QTextEdit*> textEditList;
textEditList.append(new QTextEdit(this));
QVBoxLayout* vBoxLayout = new QVBoxLayout();
widgetList[0]->setLayout(vBoxLayout);
vBoxLayout->addWidget(textEditList[0]);
setCentralWidget(tabWidget);
}
void MainWindow::newTabActionHandler()
{
widgetList.append(new QWidget(this));
tabWidget->addTab(widgetList[widgetList.size()-1], ????);
textEditList.append(new QTextEdit(this));
QVBoxLayout* vBoxLayout = new QVBoxLayout();
widgetList[widgetList.size()-1]->setLayout(vBoxLayout);
vBoxLayout->addWidget(textEditList[textEditList.size()-1]);
}
Please, put the correct code into the line where question signs take place to be (in the newTabActionHandler() method body).
tabWidget->addTab(widgetList[widgetList.size()-1], ????);
Thank You!
You have to order your code, in this case you only need to use the size of the list. but I have given the freedom to correct your code, for example widgetList and textEditList are local variables so you can not access from the slot so it is appropriate that they are members of the class.
Another recommendation is to order your code, the more readable your code is, so you can create widget and textedit and make your links without using your containers.
mainwindow.cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void newTabActionHandler();
private:
QList<QWidget*> widgetList;
QList<QTextEdit*> textEditList;
QTabWidget* tabWidget;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QMenu>
#include <QMenuBar>
#include <QTextEdit>
#include <QVBoxLayout>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QMenuBar *menuBar = new QMenuBar(this);
setMenuBar(menuBar);
QMenu* fileMenu = new QMenu("&File", this);
menuBar->addMenu(fileMenu);
QAction *newTabAction = new QAction("&New Tab", this);
fileMenu->addAction(newTabAction);
connect(newTabAction, &QAction::triggered, this, &MainWindow::newTabActionHandler);
tabWidget = new QTabWidget(this);
tabWidget->setMovable(true);
tabWidget->setTabsClosable(true);
newTabActionHandler();
setCentralWidget(tabWidget);
}
void MainWindow::newTabActionHandler()
{
QWidget *widget = new QWidget;
widgetList << widget;
tabWidget->addTab(widget, QString("Tab %1").arg(widgetList.size()-1));
QTextEdit *textEdit = new QTextEdit;
textEditList << textEdit;
QVBoxLayout* vBoxLayout = new QVBoxLayout(widget);
vBoxLayout->addWidget(textEdit);
}
MainWindow::~MainWindow()
{
}
You can find the complete example in the following link
Replace ???? by QString("Tab %1").arg(widgetList.size()-1)
Each time the "Add Client" button is pressed - a minus button, the name of the client, a counter for the client and a plus button are added in a horizontal line to the gridLayout. I want to update the count (QLabel) when the plus/minus button is pressed.
Here is my code:
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QGridLayout>
#include <QLabel>
int row = 0;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
QPushButton* minus_button = new QPushButton();
QPushButton* plus_button = new QPushButton();
minus_button->setText("-");
plus_button->setText("+");
QLabel* client_name = new QLabel(ui->lineEdit->text(), this);
QLabel* client_count = new QLabel("", this);
ui->gridLayout->addWidget(minus_button, row, 1, Qt::AlignTop|Qt::AlignHCenter);
ui->gridLayout->addWidget(client_name, row, 2, Qt::AlignTop|Qt::AlignHCenter);
ui->gridLayout->addWidget(client_count, row, 3, Qt::AlignTop|Qt::AlignHCenter);
ui->gridLayout->addWidget(plus_button, row++, 4, Qt::AlignTop|Qt::AlignHCenter);
connect(minus_button, SIGNAL(clicked(bool)), this, SLOT(minusCount()));
connect(plus_button, SIGNAL(clicked(bool)), this, SLOT(plusCount()));
}
void Widget::minusCount(){
//Here I want to somehow reference the client_count label which is in the same row
}
void Widget::plusCount(){
//Here I want to somehow reference the client_count label which is in the same row
}
EDIT: After Kevin's comment, here is the working code for anyone who may need it.
#include "widget.h"
#include "ui_widget.h"
#include <QDebug>
#include <QGridLayout>
#include <QLabel>
#include <QSignalMapper>
QSignalMapper* m_minusMapper;
QSignalMapper* m_plusMapper;
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
m_minusMapper = new QSignalMapper(this);
connect(m_minusMapper, SIGNAL(mapped(QWidget*)), this, SLOT(minusCount(QWidget*)));
m_plusMapper = new QSignalMapper(this);
connect(m_plusMapper, SIGNAL(mapped(QWidget*)), this, SLOT(plusCount(QWidget*)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
QPushButton* minus_button = new QPushButton();
minus_button->setObjectName("minus" + QString::number(row));
minus_button->setText("-");
QPushButton* plus_button = new QPushButton();
plus_button->setObjectName("plus" + QString::number(row));
plus_button->setText("+");
QLabel* client_name = new QLabel(ui->lineEdit->text(), this);
QLabel* client_count = new QLabel("0", this);
ui->gridLayout->addWidget(minus_button, row, 1, Qt::AlignVCenter|Qt::AlignHCenter);
ui->gridLayout->addWidget(client_name, row, 2, Qt::AlignVCenter|Qt::AlignHCenter);
ui->gridLayout->addWidget(client_count, row, 3, Qt::AlignVCenter|Qt::AlignHCenter);
ui->gridLayout->addWidget(plus_button, row++, 4, Qt::AlignVCenter|Qt::AlignHCenter);
connect(minus_button, SIGNAL(clicked()), m_minusMapper, SLOT(map()));
connect(plus_button, SIGNAL(clicked()), m_plusMapper, SLOT(map()));
m_minusMapper->setMapping(minus_button, client_count);
m_plusMapper->setMapping(plus_button, client_count);
}
void Widget::minusCount(QWidget *widget)
{
QLabel *client_count = qobject_cast<QLabel*>(widget);
QString initCount = client_count->text();
int newCount = initCount.toInt() - 1;
client_count->setText(QString::number(newCount));
}
void Widget::plusCount(QWidget *widget)
{
QLabel *client_count = qobject_cast<QLabel*>(widget);
QString initCount = client_count->text();
int newCount = initCount.toInt() + 1;
client_count->setText(QString::number(newCount));
}
Kevin's answer in principle is fine, but since we've got 2016 now and MSVC2010, gcc 4.7, and Clang 3.1 (and possibly earlier versions) support lambdas/C++11, I'd like to add a version without QSignalMapper:
static void minusCount(QLabel *label)
{
QString initCount = label->text();
int newCount = initCount.toInt() - 1;
label->setText(QString::number(newCount));
}
static void plusCount(QLabel *label)
{
QString initCount = label->text();
int newCount = initCount.toInt() + 1;
label->setText(QString::number(newCount));
}
void Widget::on_pushButton_clicked()
{
// ... add the labels and buttons, then:
connect(minus_button, &QPushButton::clicked,
client_count, [client_count]() { minusCount(client_count); });
connect(plus_button, &QPushButton::clicked,
client_count, [client_count]() { plusCount(client_count); });
}
Here the client_count label that the button click should change is captured in the lambda, and directly passed to the function handling it.
The minusCount and plusCount also can be static functions then, since they only operate on the label that is passed as an argument, so they are independent from any Widget instance.
The easiest way is to use a QSignalMapper
// in the constructor of your class
m_minusSignalMapper = new QSignalMapper(this);
connect(m_minusSignalMapper, SIGNAL(mapped(QWidget*)), this, SLOT(minusCount(QWidget*)));
m_plusSignalMapper = new QSignalMapper(this);
connect(m_plusSignalMapper, SIGNAL(mapped(QWidget*)), this, SLOT(plusCount(QWidget*)));
// in your button slot you connect to the respective mapper instead
connect(minus_button, SIGNAL(clicked()), m_minusMapper, SLOT(map()));
connect(plus_button, SIGNAL(clicked()), m_plusMapper, SLOT(map()));
// and you set up the mapping
m_minusMapper->setMapping(minus_button, client_count);
m_plusMapper->setMapping(plus_button, client_count);
// in the the two receiver slots, the argument is the label
void Widget::minusCount(QWidget *widget)
{
QLabel *client_count = qobject_cast<QLabel*>(widget);
}
I'm developing a Qt app in C++
I have create a layout with button bar, TreeView...
The Treeview is defined in my MainWindow.cpp
MainWindow::MainWindow()
{
setWindowTitle(QString::fromUtf8("PULS"));
resize(800,600);
setUnifiedTitleAndToolBarOnMac(true);
createDeviceStatusBar();
createSectionBar();
createTreeView();
QWidget *MainWindowWidget = new QWidget();
QVBoxLayout *MainWindowLayout = new QVBoxLayout(MainWindowWidget);
BrowserSection = new QGroupBox();
QWidget *BrowserWidget = new QWidget();
QHBoxLayout *BrowserLayout = new QHBoxLayout(BrowserWidget);
BrowserLayout->addWidget(SectionBar);
BrowserLayout->addWidget(TreeSection);
BrowserSection->setLayout(BrowserLayout);
MainWindowLayout->addWidget(DeviceSection);
MainWindowLayout->addWidget(BrowserSection);
setCentralWidget(MainWindowWidget);
show();
}
The createSectionBar() is a layout defined as below:
void MainWindow::createSectionBar()
{
SectionBar = new QGroupBox();
QVBoxLayout *SectionBarlayout = new QVBoxLayout;
SectionBarlayout->setContentsMargins(QMargins(0,0,0,0));
MusicButton = new QPushButton();
MusicButton->setFixedSize(110,150);
MusicButton->setIcon(QIcon(":/images/music.png"));
MusicButton->setIconSize(QSize(90,144));
MusicButton->setFlat(true);
MusicButton->setAutoFillBackground(true);
connect(MusicButton, SIGNAL(clicked()), this, SLOT(MusicTreeFile()));
SectionBarlayout->addWidget(MusicButton);
SectionBar->setLayout(SectionBarlayout);
}
The createTreeView() is defined as below to enable TreeView and Items.
void MainWindow::createTreeView()
{
TreeSection = new QGroupBox();
QVBoxLayout *TreeLayout = new QVBoxLayout;
MyTree = new TreeWidget();
MyTree->setSortingEnabled(true);
MyTree->setColumnWidth(0, 400);
QTreeWidgetItem* headerItem = new QTreeWidgetItem();
headerItem->setText(0,QString("File Name"));
headerItem->setText(1,QString("Size (Bytes)"));
headerItem->setText(2,QString("Date"));
MyTree->setHeaderItem(headerItem);
MyTree->setAutoFillBackground(true);
TreeLayout->addWidget(MyTree);
TreeSection->setLayout(TreeLayout);
}
What I need is to find a way to file the MyTree with
while (file != NULL && file->parent_id == folder_parent) {
QTreeWidgetItem* item = new QTreeWidgetItem();
int i;
LIBMTP_file_t *oldfile;
item->setText(0,file->filename);
Tree->addTopLevelItem(item);
....
}
here is the header file:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow();
protected:
private slots:
void MusicTreeFile();
private:
void createSectionBar();
void createTreeView();
void createDeviceStatusBar();
QGroupBox *SectionBar;
QGroupBox *TreeSection;
QGroupBox *DeviceSection;
QGroupBox *BrowserSection;
QPushButton *MusicButton;
TreeWidget *MyTree;
};
but it needs to be done only when clicking on MusicPushButton, I have already connected the MusicTreeFile() to the PushButton() action. but how to access to MyTree as it's also defined in another class..
You do not connect a signal to a class. You connect it to an instance of a class. And both of your instances are defined in MainWindow. So after both widgets are created you can call
QObject::connect(this->MusicButton, SIGNAL(clicked()), this->MyTree, SLOT(slot_name()));
With slot_name being your function
TreeWidget::slot_name{
while (file != NULL && file->parent_id == folder_parent) {
....
}
}
I had a console-game that was written on c++ and since I am currently trying to learn Qt I decided to add GUI to this program as an exercise.
So there's main window named "gui" that inherits Qwidget. It has layout QHBoxLayout* main_h_lo. Which has 2 added layouts: 1. QStackedLayout* leftpart, 2. QGridLayout* deck. The first is some sort of menu-part. It has 4 different widgets with their layouts. For example choosing game mode or printing game score. And second layout - deck - is game table, similar to chessboard.
There's constructor code which I suppose contains the problem:
gui::gui(QWidget *parent) :
QWidget(parent), pgame(nullptr)
{
QHBoxLayout* main_h_lo = new QHBoxLayout;
main_h_lo->setMargin(0);
main_h_lo->setSpacing(0);
setLayout(main_h_lo);
//leftpart-widgets initialization:
bot_or_playerW = new QWidget;
QVBoxLayout* bot_or_playerL = new QVBoxLayout;
bot_or_playerL->addWidget(new QLabel("Choose game mode"));
QPushButton* qpb1 = new QPushButton("vs Human");
QPushButton* qpb2 = new QPushButton("vs Bot");
QObject::connect(qpb1, SIGNAL(clicked()), SLOT(pvp()));
QObject::connect(qpb2, SIGNAL(clicked()), SLOT(pvb()));
bot_or_playerL->addWidget(qpb1);
bot_or_playerL->addWidget(qpb2);
bot_or_playerW->setLayout(bot_or_playerL);
choosing_colourW = new QWidget;
QVBoxLayout* choosing_colourL = new QVBoxLayout;
choosing_colourL->addWidget(new QLabel("Choose your colour"));
QPushButton* qpb3 = new QPushButton("white(2nd turn)");
QPushButton* qpb4 = new QPushButton("black(1st turn)");
QObject::connect(qpb3, SIGNAL(clicked()), SLOT(chwh()));
QObject::connect(qpb4, SIGNAL(clicked()), SLOT(chbl()));
choosing_colourL->addWidget(qpb3);
choosing_colourL->addWidget(qpb4);
choosing_colourW->setLayout(bot_or_playerL);
score_lturnW = new QWidget;
QVBoxLayout* score_lturnL = new QVBoxLayout;
lturn = new QLabel;
pturn = new QLabel;
score = new QLabel;
score_lturnL->addWidget(lturn);
score_lturnL->addWidget(pturn);
score_lturnL->addWidget(score);
score_lturnW->setLayout(score_lturnL);
after_gameW = new QWidget;
QVBoxLayout* after_gameL = new QVBoxLayout;
winner = new QLabel;
offer_to_play_again = new QLabel("Wanna play again?");
QPushButton* qpb5 = new QPushButton("yes");
QObject::connect(qpb5, SIGNAL(clicked()), SLOT(restart()));
QPushButton* qpb6 = new QPushButton("no");
QObject::connect(qpb6, SIGNAL(clicked()), qApp, SLOT(quit()));
after_gameW->setLayout(after_gameL);
leftpart = new QStackedLayout;
leftpart->addWidget(bot_or_playerW);
leftpart->addWidget(choosing_colourW);
leftpart->addWidget(score_lturnW);
leftpart->addWidget(after_gameW);
//"rightpart" init:
deck = new QGridLayout;
deck->setMargin(0);
deck->setSpacing(0);
e_pic = QPixmap("empty.png");
b_pic = QPixmap("black.png");
w_pic = QPixmap("white.png");
pic_sz = e_pic.size();
for (int i = 0; i < 8; ++i)
for (int j = 0; j < 8; ++j)
{
QPushButton* tqpb = new QPushButton;
tqpb->setIcon(e_pic);
tqpb->setIconSize(pic_sz);
std::stringstream ss;
std::string s;
ss << i << j;
ss >> s;
tqpb->setObjectName(s.c_str());
deck->addWidget(tqpb, i, j);
connect(tqpb, SIGNAL(clicked()), SLOT(turn_try()));
}
main_h_lo->addLayout(leftpart);
main_h_lo->addLayout(deck);
leftpart->setCurrentWidget(bot_or_playerW);
}
I get no error or warning. The deck part is scary and ugly but it is as expected :D. The "menu" part does not show up - that is the problem. Screen: http://i.imgur.com/Sh9PU9N.jpg .
Some comments about you code -
A layout can be given the parent on construction and it will automatically become the default layout. This saves you one command, but makes it more implicit. It all depends on what you prefer - implicit or explicit.
Loose the QObject::connect. A simple 'connect' will do.
Are you sure "black(1st turn)" is correct? In a conventional chess game, white generally goes first.
You can avoid std::stringstream and use QString::number instead.
The problem has already been mentioned by 'hyde'.
I'm creating a small application with QtCreator. It compiles, but when executing from QtCreator I'm getting "The program has inexpectedly finished" error.
If I try to execute the binary from console, I get a Segementation fault (core dumped).
Since this is the first time I start a Qt code on my own, I guess I'm missing something. Please check the following code:
Header mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class MainWindow;
class QLabel;
class QLineEdit;
class QPushButton;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
void createGUI();
private:
QLineEdit *mysqlUserLineEdit;
QLineEdit *mysqlPasswordLineEdit;
QLineEdit *albatrossIPLineEdit;
QLineEdit *albatrossPortLineEdit;
QPushButton *exitButton;
QPushButton *startButton;
};
#endif // MAINWINDOW_H
Source mainwindow.cpp:
#include <QtGui>
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
createGUI();
//connect(...)
//connect(...)
setWindowTitle(tr("Albatross MySQL simulator"));
}
MainWindow::~MainWindow()
{
}
void MainWindow::createGUI()
{
QVBoxLayout *mainLayout = new QVBoxLayout;
QHBoxLayout *settingsLayout = new QHBoxLayout;
QVBoxLayout *mysqlSettingsLayout = new QVBoxLayout;
QHBoxLayout *mysqlUserLayout = new QHBoxLayout;
mysqlUserLineEdit = new QLineEdit();
QLabel *mysqlUserLabel = new QLabel(tr("&User:"));
mysqlUserLabel->setBuddy(mysqlUserLineEdit);
mysqlUserLayout->addWidget(mysqlUserLabel);
mysqlUserLayout->addWidget(mysqlUserLineEdit);
QHBoxLayout *mysqlPasswordLayout = new QHBoxLayout;
mysqlPasswordLineEdit = new QLineEdit();
QLabel *mysqlPasswordLabel = new QLabel(tr("&Password:"));
mysqlPasswordLabel->setBuddy(mysqlPasswordLineEdit);
mysqlPasswordLayout->addWidget(mysqlPasswordLabel);
mysqlPasswordLayout->addWidget(mysqlPasswordLineEdit);
mysqlSettingsLayout->addLayout(mysqlUserLayout);
mysqlSettingsLayout->addLayout(mysqlPasswordLayout);
QVBoxLayout *networkSettingsLayout = new QVBoxLayout;
QHBoxLayout *albatrossIPLayout = new QHBoxLayout;
albatrossIPLineEdit = new QLineEdit();
QLabel *albatrossIPLabel = new QLabel(tr("&IP:"));
albatrossIPLabel->setBuddy(albatrossIPLineEdit);
albatrossIPLayout->addWidget(albatrossIPLabel);
albatrossIPLayout->addWidget(albatrossIPLineEdit);
QHBoxLayout *albatrossPortLayout = new QHBoxLayout;
albatrossPortLineEdit = new QLineEdit();
QLabel *albatrossPortLabel = new QLabel(tr("P&ort:"));
albatrossPortLabel->setBuddy(albatrossPortLineEdit);
albatrossPortLayout->addWidget(albatrossPortLabel);
albatrossPortLayout->addWidget(albatrossPortLineEdit);
networkSettingsLayout->addLayout(albatrossIPLayout);
networkSettingsLayout->addLayout(albatrossPortLayout);
settingsLayout->addLayout(mysqlSettingsLayout);
settingsLayout->addLayout(networkSettingsLayout);
QHBoxLayout *buttonsLayout = new QHBoxLayout;
exitButton = new QPushButton(tr("&Exit"));
buttonsLayout->addWidget(exitButton);
startButton = new QPushButton(tr("&Start"));
startButton->setDefault(true);
buttonsLayout->addWidget(startButton);
mainLayout->addLayout(settingsLayout);
mainLayout->addLayout(buttonsLayout);
centralWidget()->setLayout(mainLayout);
}
And finally main.cpp,, which was generated automatically with QtCreator:
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
EDIT: Ok, the problem is when using mainLayout to attach it to the mainWindow, and the last line of mainwindow.cpp. That's where it's throwing a segmentation fault. What should I set as central widget? Or is there any other way of attaching the layout to the mainwindow widget?
In general this behavior in creator is due to a SEGFAULT or a missing library.
Your code
mysqlPasswordLabel->setBuddy(mysqlPasswordLineEdit);
mysqlPasswordLayout->addWidget(mysqlPasswordLabel);
mysqlPasswordLayout->addWidget(mysqlPasswordLineEdit);
is the cause. You don't initialize mysqlPasswordLineEdit which causes a SEGFAULT