I have a table with some data. However since not all the information fits into the table, the user should have the option to get further information on the line by pressing a button in this line. I currently add the buttons in the following way:
int lastRow = table->rowCount();
table->insertRow(lastRow);
QWidget* pWidget = new QWidget();
pWidget->setFixedWidth(30);
LdtButton* btn_help = new LdtButton();
btn_help->addInactiveIcon(QPixmap(":/icons/help_inactive.png"));
btn_help->addHoverIcon(QPixmap(":/icons/help_hovered.png"));
QHBoxLayout* pLayout = new QHBoxLayout(pWidget);
pLayout->addWidget(btn_help);
pLayout->setAlignment(Qt::AlignCenter);
pLayout->setContentsMargins(0, 0, 0, 0);
pWidget->setLayout(pLayout);
table->setCellWidget(lastRow, 1, pWidget);
However I do not really have a idea how to connect these buttons, so I get the row the button was in when it gets pressed, so I can output the appropriate informations. (not every row has a button)
Use the signal QPushButton::clicked and a lambda to call the right method (use the capture to pass the row).
QTableWidget* table = new QTableWidget(0, 2);
QStringList values = {"foo", "bar", "spam"};
for (QString const& value : values)
{
int lastRow = table->rowCount();
table->insertRow(lastRow);
table->setItem(lastRow, 0, new QTableWidgetItem(value));
QWidget* pWidget = new QWidget();
QPushButton* btn_help = new QPushButton("help");
QHBoxLayout* pLayout = new QHBoxLayout(pWidget);
pLayout->addWidget(btn_help);
pLayout->setAlignment(Qt::AlignCenter);
pLayout->setContentsMargins(0, 0, 0, 0);
pWidget->setLayout(pLayout);
table->setCellWidget(lastRow, 1, pWidget);
// Call your method in the lambda
QObject::connect(btn_help, &QPushButton::clicked, [lastRow]() {qDebug() << "Show help for " << lastRow; });
}
table->show();
It will display:
Show help for 0
Show help for 1
Show help for 2
Related
I am implementing a QTableWidget, the selection rectangle seems not to be disappearing even after I finish editing and change my selection to other cells.
Below is a screenshot of the QTableWidget.
Below is the code for constructing the tablewidget, rows are added dynamically via a QPushButton:
{
setObjectName(obj_name);
layout = new QVBoxLayout();
table = new QTableWidget(this);
table->verticalHeader()->setVisible(false);
table->verticalHeader()->setDefaultSectionSize(20);
table->setFixedWidth(180);
table->setColumnCount(3);
table->setColumnWidth(0,75);
table->setColumnWidth(1, 75);
table->setColumnWidth(2, 25);
QStringList header = { "Tag", "Threshold" ,""};
table->setHorizontalHeaderLabels(header);
table->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);
add = new QPushButton("+", this);
add->setObjectName("btn_threshold_add");
layout->addWidget(table);
layout->addWidget(add);
setLayout(layout);
connect(add, SIGNAL(clicked()), this, SLOT(add_row()));
}
Below is the code for add_row() SLOT, triggers when user clicked the add button:
void TagThresholdWidget::add_row()
{
int row = table->rowCount();
QPushButton *del = new QPushButton("-", table);
table->insertRow(row);
table->setCellWidget(row, 2, del);
connect(del, SIGNAL(clicked()), this, SLOT(remove_row()));
}
Anyone has any clue to how to solve this problem? Its seems like a Qt graphical paint bug to me
for(int i=0; i<page.size(); i++){
User user= Poco::AnyCast<User>(*it);
ui.table->setItem(i,0,new QTableWidgetItem(user.userName));
ui.table->setItem(i,1,new QTableWidgetItem(user.sex));
ui.table->setItem(i,2,new QTableWidgetItem(user.age));
QPushButton* btn_edit = new QPushButton();
btn_edit = new QPushButton();
btn_edit->setText("Edit");
ui.table->setCellWidget(i,3,(QWidget*)btn_edit);
++it;
}
I add a QPushButton into the cell with the function setCellWidget(),
I know, if it's a QTableWidgetItem, I can use :
ui.table->item(0,3)->setTextAlignment(QT::AlignHCenter)
But it is a Widget,
QTableWidgetItem item = ui.table->item(0,3);
the item is null.
I can get the cell by use
ui.table->cellWidget(0,3).
How should I do to make the button centered in the cell?
Try this:
QWidget* pWidget = new QWidget();
QPushButton* btn_edit = new QPushButton();
btn_edit->setText("Edit");
QHBoxLayout* pLayout = new QHBoxLayout(pWidget);
pLayout->addWidget(btn_edit);
pLayout->setAlignment(Qt::AlignCenter);
pLayout->setContentsMargins(0, 0, 0, 0);
pWidget->setLayout(pLayout);
ui.table->setCellWidget(i, 3, pWidget);
I have custom window class
#define NAME_WIDTH 150
#define NAME_HEIGHT 20
ObjectWindow::ObjectWindow(QWidget * parent)
{
}
void ObjectWindow::SetKey(KeyObject * keyObj)
{
QGridLayout * layout = new QGridLayout(this);
nameField = new QTextEdit(this);
nameField->setText(keyObj->name);
nameField->setGeometry(nameField->geometry().x(), nameField->geometry().y(),
NAME_WIDTH, NAME_HEIGHT);
layout->addWidget(nameField);
QHBoxLayout * picsLayout = new QHBoxLayout(this);
for(std::vector<ImageInstance*>::iterator imgObj = keyObj->images.begin(); imgObj != keyObj->images.end(); imgObj++)
{
QComboBox * folderList = new QComboBox;
picsLayout->addWidget(folderList);
QImage image((*imgObj)->imgPath);
QLabel * picLabel = new QLabel;
picLabel->setPixmap(QPixmap::fromImage(image).scaled(200, 200, Qt::KeepAspectRatio, Qt::SmoothTransformation));
picsLayout->addWidget(picLabel);
}
layout->addLayout(picsLayout, 2, 0);
QPushButton * saveBtn = new QPushButton(this);
saveBtn->setText("Save");
connect(saveBtn, SIGNAL(released()),this, SLOT(Save()));
layout->addWidget(saveBtn);
setLayout(layout);
}
What i need is
small text field to set the name, I don't unerstand why SetGeometry doesn't work
dropdown list above each image. I can create QHVertical layout for each set of image and list, but maybe there is more simple way to do it?
If you just want the user to set the name, a QLineEdit is probably enough.
Then the main advantage of using a QGridLayout is that you don't need to create other layouts. It acts like a grid where you put your widgets, a bit like Excel (and other spreadsheet programs).
Oh and I see that you are not constructing the Widgets in the constructor (which seems to be empty), that's what people usually do because constructing the UI can be expensive and you just want to update it when relevant, not rebuilding the whole UI just to update a field. But without more code I cannot tell when this function is being called.
You can try something like this:
QGridLayout * layout = new QGridLayout(this);
nameField = new QLineEdit(this);
nameField->setText(keyObj->name);
layout->addWidget(nameField, 0, 0, -1, 1); // expand to the right edge
int currentColumn = 0;
for(std::vector<ImageInstance*>::iterator imgObj = keyObj->images.begin(); imgObj != keyObj->images.end(); imgObj++)
{
QComboBox * folderList = new QComboBox;
layout->addWidget(folderList, 1, currentColumn);
QPixmap pixmap((*imgObj)->imgPath);
pixmap = pixmap.scaled(200, 200, Qt::KeepAspectRatio, Qt::SmoothTransformation);
QLabel * picLabel = new QLabel(this);
picLabel->setPixmap(pixmap);
layout->addWidget(picLabel, 2, currentColumn);
++currentColumn;
}
QPushButton * saveBtn = new QPushButton("Save", this);
connect(saveBtn, SIGNAL(released()),this, SLOT(Save()));
layout->addWidget(saveBtn, 3, 0, -1, 1);
setLayout(layout);
But it doesn't seem to be a good idea to add those widgets horizontally like that. What would happen if there are 100 items in this vector? You should investigate in using something like a QScrollArea or modifying the UI to give your client the best way to view and edit those (but without more context it seems difficult to give your more advice).
I am trying to adjust a LineEdit and PushButton width in a QDialog window. The LineEdit should be 20 times wider than then button, so it's long enough to show the whole path. Below is my code, I tried several ways, but they all got similar layout (see screenshot). I want to make the Option window at least 2 times wider to make the LineEdit wide enough. How should I do that?
This is my code:
this->setWindowTitle(tr("Options"));
QGridLayout* logLayout = new QGridLayout;
QLineEdit _logPathLE = new QLineEdit;
logLayout->addWidget(_logPathLE, 0, 0);
logLayout->setColumnStretch(0, 20); // 1st: try with setStretch
//_logPathLE->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred); // 2nd try with setSizePolicy
//logLayout->addWidget(logLocation, 0, 0, 0, 20); // 3rd: try with span multiple columns
QPushButton* browseFolder = new QPushButton(tr("..."));
logLayout->addWidget(browseFolder, 0, 1);
logLayout->setColumnStretch(1, 1);
//browseFolder->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
//logLayout->addWidget(browseFolder, 0, 20, 0, 1);
QGroupBox* optGroupBox = new QGroupBox(tr("Log location"));
optGroupBox->setLayout(logLayout);
QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
connect(btns, SIGNAL(accepted()), this, SLOT(accept()));
connect(btns, SIGNAL(rejected()), this, SLOT(reject()));
QVBoxLayout* options = new QVBoxLayout;
options->addWidget(optGroupBox);
options->addWidget(btns);
this->setLayout(options);
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);