In an attempt to create a small search GUI i wanted that whenever a user types in a TextEdit a program searches for all plausible results and shows them in a QGroupBox inside a QScollArea.
I now want to add that when i click on the QGroupBox a new QDialog opens and shows the found result details. (That deletes itself when it closes - the small details window not the QGroupBox)
I managed to do everything except that when i click on the QGroupBox a new QDialog opens.
Here is my code:
organizer.h
class Organizer : public QMainWindow
{
Q_OBJECT
private:
QGroupBox* generateSearchResultEnclosure(const std::string& item_name,const std::string& classer_name, const unsigned row, const unsigned column);
std::vector<QGroupBox*> search_results;
QGridLayout *scroll_layout;
unsigned nRows;
public:
explicit Organizer(ItemOrganizer* item_org,QWidget *parent = 0);
~Organizer();
private slots:
void generateClickedWindowItemResult(const std::string& exact_item_name, QWidget* parent);
void on_searchField_textChanged();
void on_pushButton_clicked();
void on_pushButton_2_clicked();
void updateFormComponentAddAvailable();
void updateFormAdd2ClsrAvailable();
void updateFormInsrtClsrAvailable();
void on_addClasser_PushButton_clicked();
private:
Ui::Organizer *ui;
ComponentAdd *form_cmp_add;
AddToClasser *form_add2_clsr;
InsertClasser *form_insrt_clsr;
ItemOrganizer *item_organizer;
};
organizer.cpp
(On QTextEdit text change):
void Organizer::on_searchField_textChanged()
{
QWidget *wdg=ui->scrollArea->takeWidget();
delete wdg;
QWidget* blank_wdg=new QWidget();
scroll_layout=new QGridLayout(blank_wdg);
//widget->setLayout(layout);
ui->scrollArea->setWidget(blank_wdg);
ui->scrollArea->setWidgetResizable(true);
if ((ui->searchField->toPlainText()).isEmpty())
return;
// Searching and generating a QGroupBox for each hit
std::vector<SearchResult> res=item_organizer->search((ui->searchField->toPlainText()).toUtf8().constData());
for (SearchResult &sr:res)
{
QGroupBox *win=generateSearchResultEnclosure(sr.cmp->name,sr.classer_name,sr.row,sr.column);
scroll_layout->addWidget(win);
win->show();
}
// Corecting QScrollArea widget size to fit all QGroupBox results
unsigned row_count=0;
if (scroll_layout->count()!=0)
row_count=scroll_layout->rowCount();
if(row_count>= nRows)
{
int h = 1.0*(ui->scrollArea->width() - scroll_layout->verticalSpacing()*(nRows+1.6))/nRows;
int hCorrected = h*row_count + scroll_layout->verticalSpacing()*(row_count+2);
ui->scrollArea->widget()->setFixedHeight(hCorrected);
}
ui->scrollArea->widget()->setFixedWidth(ui->scrollArea->viewport()->width());
}
organizer.cpp (Function that generates QGroupBox):
QGroupBox* Organizer::generateSearchResultEnclosure(const std::string& item_name,const std::string& classer_name, const unsigned row, const unsigned column)
{
QGroupBox* holder=new QGroupBox();
QVBoxLayout *layout_main=new QVBoxLayout;
QGroupBox *item_grp=new QGroupBox();
QGroupBox *clsr_grp=new QGroupBox();
QGroupBox *row_grp=new QGroupBox();
QGroupBox *column_grp=new QGroupBox();
QHBoxLayout *layout_item=new QHBoxLayout;
QHBoxLayout *layout_classer=new QHBoxLayout;
QHBoxLayout *layout_row=new QHBoxLayout;
QHBoxLayout *layout_column=new QHBoxLayout;
QLabel *item_label=new QLabel(tr("Item Name: "));
QLabel *clsr_label=new QLabel(tr("Classer Name: "));
QLabel *row_label=new QLabel(tr("Row: "));
QLabel *column_label=new QLabel(tr("Column: "));
QLineEdit *item_edit=new QLineEdit();
QLineEdit *classer_edit=new QLineEdit();
QLineEdit *row_edit=new QLineEdit();
QLineEdit *column_edit=new QLineEdit();
item_edit->setReadOnly(true);
classer_edit->setReadOnly(true);
row_edit->setReadOnly(true);
column_edit->setReadOnly(true);
item_edit->setText(item_name.c_str());
classer_edit->setText(classer_name.c_str());
row_edit->setText(QString::number(row));
column_edit->setText(QString::number(column));
layout_item->addWidget(item_label);
layout_item->addWidget(item_edit);
layout_classer->addWidget(clsr_label);
layout_classer->addWidget(classer_edit);
layout_row->addWidget(row_label);
layout_row->addWidget(row_edit);
layout_column->addWidget(column_label);
layout_column->addWidget(column_edit);
item_grp->setLayout(layout_item);
clsr_grp->setLayout(layout_classer);
row_grp->setLayout(layout_row);
column_grp->setLayout(layout_column);
layout_main->addWidget(item_grp);
layout_main->addWidget(clsr_grp);
layout_main->addWidget(row_grp);
layout_main->addWidget(column_grp);
layout_main->addStretch();
holder->setLayout(layout_main);
//holder->setMaximumHeight(ui->scrollArea->height()/2 - 10);
holder->setStyleSheet("QGroupBox {border: 2px solid gray; border-radius: 1px;} "
"QGroupBox::title {background-color: transparent; subcontrol-position: top left; padding:2 13px;}");
connect(holder, SIGNAL(clicked(bool)),this,SLOT(generateClickedWindowItemResult(item_name,holder)));
return holder;
}
Now i figured that i cannot connect that SLOT to that signal (since SIGNAL and SLOT need to have the same arguments) even though something like that would work for me.
Here is the part where i generate that QDialog in case that is needed as part of a problem solving. (Though its only form filling)
void Organizer::generateClickedWindowItemResult(const std::string& exact_item_name, QWidget *parent)
{
Component* cmp=item_organizer->getComponentByFullName(exact_item_name,true);
QDialog* cmp_window=new QDialog(parent);
QVBoxLayout *layout_main=new QVBoxLayout;
QGroupBox *item_name_grp=new QGroupBox();
QGroupBox *descr_grp=new QGroupBox();
QGroupBox *url_grp=new QGroupBox();
QGroupBox *tags_grp=new QGroupBox();
QGroupBox *quantity_grp=new QGroupBox();
QGroupBox *future_quantity_grp=new QGroupBox();
QHBoxLayout *layout_item_name=new QHBoxLayout;
QHBoxLayout *layout_descr=new QHBoxLayout;
QHBoxLayout *layout_url=new QHBoxLayout;
QHBoxLayout *layout_tags=new QHBoxLayout;
QHBoxLayout *layout_quantity=new QHBoxLayout;
QHBoxLayout *layout_future_quantity=new QHBoxLayout;
QLabel *item_name_label=new QLabel(tr("Item Name: "));
QLabel *descr_label=new QLabel(tr("Item Description: "));
QLabel *url_label=new QLabel(tr("Datasheet URL: "));
QLabel *tags_label=new QLabel(tr("Item Tags: "));
QLabel *quantity_label=new QLabel(tr("Item Current Quantity: "));
QLabel *future_quantity_label=new QLabel(tr("Item current+ordered quantity: "));
QLineEdit *item_name_edit=new QLineEdit();
QTextEdit *descr_edit=new QTextEdit();
QTextEdit *url_edit=new QTextEdit();
QTextEdit *tags_edit=new QTextEdit();
QLineEdit *quantity_edit=new QLineEdit();
QLineEdit *future_quantity_edit=new QLineEdit();
item_name_edit->setReadOnly(true);
descr_edit->setReadOnly(true);
url_edit->setReadOnly(true);
tags_edit->setReadOnly(true);
quantity_edit->setReadOnly(true);
future_quantity_edit->setReadOnly(true);
item_name_edit->setText(cmp->name.c_str());
descr_edit->setText(cmp->description.c_str());
url_edit->setText(cmp->url.c_str());
// TODO WRITE TAGS
//tags_edit->setText(cmp->tags);
quantity_edit->setText(QString::number(cmp->quantity));
future_quantity_edit->setText(QString::number(cmp->future_quantity));
layout_item_name->addWidget(item_name_label);
layout_item_name->addWidget(item_name_edit);
layout_descr->addWidget(descr_label);
layout_descr->addWidget(descr_edit);
layout_url->addWidget(url_label);
layout_url->addWidget(url_edit);
layout_tags->addWidget(tags_label);
layout_tags->addWidget(tags_edit);
layout_quantity->addWidget(quantity_label);
layout_quantity->addWidget(quantity_edit);
layout_future_quantity->addWidget(future_quantity_label);
layout_future_quantity->addWidget(future_quantity_edit);
item_name_grp->setLayout(layout_item_name);
descr_grp->setLayout(layout_descr);
url_grp->setLayout(layout_url);
tags_grp->setLayout(layout_tags);
quantity_grp->setLayout(layout_quantity);
future_quantity_grp->setLayout(layout_future_quantity);
layout_main->addWidget(item_name_grp);
layout_main->addWidget(descr_grp);
layout_main->addWidget(url_grp);
layout_main->addWidget(tags_grp);
layout_main->addWidget(quantity_grp);
layout_main->addWidget(future_quantity_grp);
layout_main->addStretch();
cmp_window->setLayout(layout_main);
cmp_window->setAttribute(Qt::WA_DeleteOnClose);
cmp_window->show();
}
How can i connect a on clicked signal from my QGroupBox to generate a QDialog and pass a parameter to QDialog as well as put that QGroupBox to be its parent?
Related
I want to add a QLineEdit to a QTabWidget but I always get a
Segmentation fault, SIGSEGV
I did it the following way:
QHBoxLayout *layout = new QHBoxLayout;
QWidget *Tab = new QWidget(ui->tabWidget);
ui->tabWidget->addTab(Tab, "Tab1");
Tab->setLayout(layout);
QLineEdit *lE = new QLineEdit();
lE->setObjectName("Text");
lE->setText("Hello");
ui->tabWidget->widget(0)->layout()->addWidget(lE);
This way works for adding a QPushButton but somehow it doesn't work for a QLineEdit.
you can add a widget to a cell
example:
//
QWidget* pWidget = new QWidget();
QLineEdit* foo = new QLineEdit(this);
foo->setText("Edit");
QHBoxLayout* pLayout = new QHBoxLayout(pWidget);
pLayout->addWidget(foo);
pLayout->setAlignment(Qt::AlignCenter);
pLayout->setContentsMargins(0, 0, 0, 0);
pWidget->setLayout(pLayout);
this->ui->myTable->setCellWidget(1, 1, pWidget);
I want to do serial communication in the QT inside, according to the number of serial ports to dynamically generate label, LineEdit, Button, and these three buttons can pull down the scroll bar when the size of the interface, how to do well, I write this below is dead of.
The effect of encapsulation into a method
The interface was washed last
Define QGridLayout insude QScrollArea. And add your new widgets into
that layout in code. QGridLayout::addWidget
Define table where you will show several widgets in table cells. That real complicated way.
void BaseUi::BaseScrollArea()
{
QScrollArea *pArea = new QScrollArea();
QWidget *pWidget = new QWidget();
pWidget->setStyleSheet("QWidget" "{background:white;}");
m_vbox_layout = new QVBoxLayout();
m_vbox_layout->addSpacerItem(new QSpacerItem(100, 30,
QSizePolicy::Expanding, QSizePolicy::Expanding));
pWidget->setLayout(m_vbox_layout);
pArea->setWidget(pWidget);
pArea->setWidgetResizable(true);
m_main_layout = new QVBoxLayout();
m_main_layout->addWidget(pArea);
}
void BaseUi::addAutoRecordUi(QString lab_neme, QString ledit_name)
{
QWidget *page = new QWidget;
QGridLayout *layout = new QGridLayout(page);
QLabel *label = new QLabel;
label->setText(lab_neme);
label->setFont(font());
QLineEdit *ledit = new QLineEdit;
ledit->setText(ledit_name);
ledit->setFont(font());
layout->addWidget(label, 0, 1);
layout->addWidget(ledit, 0, 2);
page->setLayout(layout);
m_vbox_layout->insertWidget(m_vbox_layout->count()-1, page);
}
void BaseUi::addMulRecordUi(QString lab_neme, QString ledit_name, QString
but_name)
{
QWidget *page = new QWidget;
QGridLayout *layout = new QGridLayout(page);
QLabel *label = new QLabel;
label->setText(lab_neme);
label->setFont(font());
QLineEdit *ledit = new QLineEdit;
ledit->setText(ledit_name);
ledit->setFont(font());
QPushButton *but = new QPushButton(but_name);
but->setFont(font());
layout->addWidget(label, 0, 1);
layout->addWidget(ledit, 0, 2);
layout->addWidget(but, 0, 3);
page->setLayout(layout);
m_vbox_layout->insertWidget(m_vbox_layout->count()-1, page);
}
I have simple class that inherits QDialog, I add dynamically elements
and my elements are located in the center, but I want to add them at the top.
class CustomDialog : public QDialog {
Q_OBJECT
private:
QVBoxLayout *mainLayout;
CustomDialog()
{
mainLayout = new QVBoxLayout();
setLayout(mainLayout);
}
public:
void update()
{
QLabel* label = new QLabel("some text");
QVBoxLayout *verLayout = new QVBoxLayout;
verLayout->addStretch();
verLayout->setAlignment(Qt::AlignTop);
verLayout->addWidget(label, Qt::AlignTop);
mainLayout->setAlignment(Qt::AlignTop);
mainLayout->addLayout(verLayout, Qt::AlignTop);
}
};
What am I doing wrong? and why my dynamically added elements always in center?
I understand that you want to place it and that the top is shown, so you could use QSpacerItem to push it.
class CustomDialog : public QDialog {
Q_OBJECT
QVBoxLayout *mainLayout;
public:
CustomDialog(QWidget *parent=0): QDialog(parent)
{
mainLayout = new QVBoxLayout(this);
QSpacerItem *verticalSpacer = new QSpacerItem(20, 217, QSizePolicy::Minimum, QSizePolicy::Expanding);
mainLayout->addItem(verticalSpacer);
addWidgets("1");
addWidgets("2");
}
private:
void addWidgets(const QString &text)
{
QLabel* label = new QLabel(text);
QVBoxLayout *verLayout = new QVBoxLayout;
verLayout->addStretch();
verLayout->setAlignment(Qt::AlignTop);
verLayout->addWidget(label, Qt::AlignTop);
mainLayout->setAlignment(Qt::AlignTop);
mainLayout->insertLayout(mainLayout->count()-1, verLayout);
}
};
Or if you want it to have a reverse order you must insert it in the first position with:
mainLayout->insertLayout(0, verLayout);
Note: The use of addLayout is incorrect since the second parameter is stretch.
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) {
....
}
}
Basically I have a QTabWidget. At first it has a form widget, widget1. After that form is done being interacted with, the new widget2 form should take over that same tab.
I thought tabWidget->setCurrentWidget(new widget2()); would work, but it's basically an overload for setCurrentIndex(int).
Does anyone know of a way to do this?
You can use a QStackedWidget for this type of thing, in a tab or elsewhere.
Put all the widgets you'll want to display in that tab inside a single QStackedWidget, and place that stacked widget in a tab.
Here's a quick'n'dirty demo:
#include <QtGui>
class W: public QWidget
{
Q_OBJECT
public:
W(QWidget *parent=0): QWidget(parent)
{
// stacked widget displays one of its "children" at a time
QStackedWidget *sw = new QStackedWidget;
QPushButton *b1 = new QPushButton("hello");
sw->addWidget(b1);
QPushButton *b2 = new QPushButton("world");
sw->addWidget(b2);
// tab widget and simplistic layout
QTabWidget *tw = new QTabWidget(this);
tw->addTab(sw, "tab");
QHBoxLayout *l = new QHBoxLayout;
l->addWidget(tw);
setLayout(l);
// signal mapper to demo the widget switching
QSignalMapper *m = new QSignalMapper(this);
connect(b1, SIGNAL(clicked()), m, SLOT(map()));
m->setMapping(b1, 1);
connect(b2, SIGNAL(clicked()), m, SLOT(map()));
m->setMapping(b2, 0);
connect(m, SIGNAL(mapped(int)), sw, SLOT(setCurrentIndex(int)));
}
};