How to prevent first CellWidget from collapsing when adding rows to QTableWidget - qt

I'm using this simple code to try to understand why the size of the widget in the first row is changing while adding rows to the table but all other rows remain intact...
This is the simple code I'm trying:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
#include <QCheckBox>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStringList HorizontalHeaders;
HorizontalHeaders << "Number" << "Test";
ui->tableWidget->setColumnCount(2);
ui->tableWidget->setHorizontalHeaderLabels(HorizontalHeaders);
ui->tableWidget->horizontalHeader()->setVisible(true);
ui->tableWidget->verticalHeader()->setVisible(false);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_spinBox_valueChanged(int arg1)
{
ui->tableWidget->setRowCount(arg1);
ui->tableWidget->clear();
for(int i = 0; i < arg1; i++){
QWidget* thiswidget = new QWidget();
QHBoxLayout* thislayout = new QHBoxLayout(thiswidget);
QCheckBox* thischeckbox = new QCheckBox();
QLabel* thislabel = new QLabel(QString::number(i));
thislayout->addWidget(thischeckbox);
thislayout->addWidget(thislabel);
ui->tableWidget->setCellWidget(i, 0, thiswidget);
ui->tableWidget->setItem(i, 1, new QTableWidgetItem("Test " + QString::number(i)));
ui->tableWidget->setRowHeight(i, thiswidget->height());
}
}
the result with just 2 rows:
the result with many row:

Related

How to get the row value from Qtable widget

Actually i am inserting combo box in one column on my table and when one of the combo box from the table is selected i want to get the row value . How this can be done ?
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"QComboBox"
#include "QDebug"
#include "QModelIndexList"
#include "QTableWidgetItem"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QComboBox *s = new QComboBox;
s->insertItem(1,"INt");
ui->tableWidget->setCellWidget(1,1,s);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_tableWidget_clicked(const QModelIndex &index)
{
qDebug("ROW %d",index.row());
}
I tried something like this but it didnt give the row value where i have inserted the combo box and from other places it was returning the row value
I'm not so sure what you are trying to achieve, but maybe you are looking for a ItemDelegate that can be set for specific rows or columns, but not for a specific element inside the table. Maybe the posted solution would help you to create minimal reproducible examples.
#include <QApplication>
#include <QComboBox>
#include <QDebug>
#include <QTableWidget>
#include <QStyledItemDelegate>
class ComboBoxDelegate : public QStyledItemDelegate{
public:
virtual QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
auto s = new QComboBox(parent);
s->insertItem(1, "First");
s->insertItem(2, "Second");
return s;
}
};
int main(int argc, char** args) {
QApplication app(argc, args);
auto table = new QTableWidget;
table->setRowCount(2);
table->setColumnCount(2);
table->setItemDelegateForColumn(0, new ComboBoxDelegate);
auto s = new QComboBox;
s->insertItem(1, "First");
s->insertItem(2, "Second");
table->setCellWidget(1, 1, s);
QObject::connect(table, &QTableWidget::itemChanged, [&](QTableWidgetItem* item) {
qDebug() << item->row();
});
table->show();
app.exec();
}

Can't change color of item in QListView

I have the following code;
QStringListModel *model = new QStringListModel();
QStringList list;
ui.listViewResults->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui.listViewResults->setViewMode(QListView::ListMode);
list << "A";
list << "B";
list << "C";
model->setStringList(list);
QModelIndex vIndex = model->index(0, 0);
QMap<int, QVariant> vMap = model->itemData(vIndex);
vMap.insert(Qt::BackgroundRole, QVariant(QBrush(Qt::red)));
model->setItemData(vIndex, vMap);
ui.listViewResults->setModel(model);
Yet, the color does not seem to change, any ideas? Thanks!
Use QStandartItemModel and QStandartItem if you need different background for each item. Or you can even make your own model/item subclassing QAbstractItemModel
Example of using QStandartItemModel and QStandartItem
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QStringListModel>
#include <QStandardItemModel>
#include <QListView>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStandardItemModel *model = new QStandardItemModel();
QList<QStandardItem *> list;
ui->listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
ui->listView->setViewMode(QListView::ListMode);
list << new QStandardItem("A");
list << new QStandardItem("B");
list << new QStandardItem("C");
model->appendColumn(list);
QModelIndex vIndex = model->index(0, 0);
QMap<int, QVariant> vMap = model->itemData(vIndex);
vMap.insert(Qt::BackgroundRole, QVariant(QBrush(Qt::red)));
model->setItemData(vIndex, vMap);
ui->listView->setModel(model);
}
MainWindow::~MainWindow()
{
delete ui;
}

Qt Grid add cutting lines

Such like title I say,
The game.cpp:
#include "game.h"
#include "ui_game.h"
#include "qdebug.h"
Game::Game(QWidget *parent) :
QWidget(parent),
ui(new Ui::Game)
{
ui->setupUi(this);
QPalette palette;
QPixmap pixmap(":/bgimg");
palette.setBrush(this->backgroundRole(),QBrush(pixmap));
this->setPalette(palette);
InitLayout(6,6);
}
Game::~Game()
{
delete ui;
}
void Game::InitLayout(int widthNum, int heightNum)
{
ui->grid->setGeometry(QRect(0,0,1000,800));
for(int i=0; i< heightNum;i++)
{
for(int j=0;j<widthNum;j++)
{
int total = i*10+j;
QString s = QString::number(total);
qDebug() << s << "\n";
QLabel*item = new QLabel(this);
//item->setText(s);
ui->grid->addWidget(item,i+1,j+1);
}
}
}
And cell.cpp
#include "cell.h"
cell::cell(QWidget *parent):
QLabel(parent)
{
this->setGeometry(0,0,20,20);
QPixmap qpixmap(":/qizi");
this->setPixmap(qpixmap);
}
I want to show the cutting line int Grid(You know that grid are divided into many cell by line). I can't find to property in Grid.

Read multiple texts Qt

i am doing Qt project about displaying many texts. in detail, after 1st text display, it will close then display next file. My problem here was that just the last file displayed. all link resource paths are correct. Please help me fix me. Thanks in advance
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QString>
#include <QStackedWidget>
#include <QTextBrowser>
#include <QStringList>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStringList L;
L << ":/sample.txt" << ":/idp.txt";
foreach (QString str, L){
QFile file(str);
if (!file.open(QIODevice::ReadOnly))
QMessageBox::information(0,"error file path", file.errorString());
QString name = file.fileName();
QStringList parts = name.split("/");
QString lastBit = parts.at(parts.size()-1);
statusBar()->showMessage(lastBit);
QTextStream out(&file);
QString txt = out.readAll();
QStackedWidget *temp = new QStackedWidget();
QTextBrowser *textbrs = new QTextBrowser();
textbrs->setText(txt);
temp->addWidget(textbrs);
setCentralWidget(temp);
file.close();
}
}
MainWindow::~MainWindow()
{
delete ui;
}
Something like this:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QString>
#include <QStackedWidget>
#include <QTextBrowser>
#include <QStringList>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
L << ":/sample.txt" << ":/idp.txt"; //Class member of Type QStringList
textbrs = new QTextBrowser(); //Class member of Type QTextBrowser*
ui->centralWidget->layout()->addWidget(textbrs);
timer = new QTimer(); //Class member of Type QTimer*
timer->setInterval(5000);
connect(timer,SIGNAL(timeout()),this,SLOT(slotFileAction()));
timer->start();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slotFileAction()
{
static int count = 0;
if(count >= L.size())
timer->stop();
QString str = L.at(count);
count++;
QFile file(str);
if (!file.open(QIODevice::ReadOnly))
QMessageBox::information(0,"error file path", file.errorString());
QString name = file.fileName();
QStringList parts = name.split("/");
QString lastBit = parts.at(parts.size()-1);
statusBar()->showMessage(lastBit);
QTextStream out(&file);
QString txt = out.readAll();
textbrs->setText(txt);
file.close();
}
Each time you will replace the old QStackedWidget by
setCentralWidget(temp);
The example to use QStackedWidget in Qt help document is following:
QWidget *firstPageWidget = new QWidget;
QWidget *secondPageWidget = new QWidget;
QWidget *thirdPageWidget = new QWidget;
QStackedWidget *stackedWidget = new QStackedWidget;
stackedWidget->addWidget(firstPageWidget);
stackedWidget->addWidget(secondPageWidget);
stackedWidget->addWidget(thirdPageWidget);
QVBoxLayout *layout = new QVBoxLayout;
layout->addWidget(stackedWidget);
setLayout(layout);
So, you should add multiple QTextBrowsers in QStackedWidget by addWidget() and use setCentralWiget() just once.
Hope helpful.

duplicate buttons

I have the following problem I've been struggeling with. I have a list of toolbuttons placed in a scroll area. I want to make a second scroll area with push buttons that duplicate the text of the tool buttons, but only for the toolbuttons that are selected. For example let's select toolbuttons 1,2 and 3. Then when I push an "update" button, a scrollarea with pushbuttons 1,2 and three should appear. This is my code:
CPP-file:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtGui>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
scrollArea.setParent(ui->centralWidget);
scrollArea.setGeometry(50,50,200,300);
scrollArea.setWidget(&viewport);
viewport.setLayout(&layout);
scrollArea2.setParent(ui->centralWidget);
scrollArea2.setGeometry(350,50,200,300);
scrollArea2.setWidget(&viewport2);
viewport2.setLayout(&layout2);
update.setParent(ui->centralWidget);
update.setGeometry(50,400,100,50);
update.setText("update");
addButtons();
connect(&update,SIGNAL(clicked()),this,SLOT(refreshScrollArea()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::addButtons()
{
for(int i=0; i<5;i++)
{
QToolButton *button = new QToolButton;
button->setCheckable(true);
buttons<<button;
buttons[i]->setText(QString::number(i+1));
buttons[i]->setMinimumSize(200,50);
layout.addWidget(buttons[i]);
}
viewport.resize(200,5*50);
}
void MainWindow::refreshScrollArea()
{
while (!layout2.isEmpty())
{
delete layout2.takeAt(0);
}
int selected_index=0;
for(int i=0; i<5;i++)
{
if (buttons[i]->isChecked())
{
QPushButton * button = new QPushButton;
button->setText(buttons[i]->text());
layout2.addWidget(button);
selected_index++;
}
}
viewport2.resize(150,50*selected_index);
}
header file:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtGui>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void addButtons();
void refreshScrollArea();
private:
Ui::MainWindow *ui;
QVector<QToolButton*> buttons;
QScrollArea scrollArea;
QScrollArea scrollArea2;
QVBoxLayout layout;
QVBoxLayout layout2;
QWidget viewport;
QWidget viewport2;
QPushButton update;
};
#endif // MAINWINDOW_H
Main:
#include <QtGui/QApplication>
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
When I push the update-button once, it works perfectly, but when I select different tool buttons and push update again it seems like the buttons are being stacked as if the layout is not empty. However when I select no toolbutton and push update there are no buttons, so the layout is emptied. Can anybody see what I´m doing wrong?
An example of the 'update' code:
// you clear your duplicate layout
int num = layout2->count();
for (int i = 0; i < num; ++i
{
delete layout2->itemAt(0);
}
// you create duplicate buttons for checked initial buttons
for (int i = 0; layout1->count(); ++i)
{
QPushButton* btn = (QPushButton*)layout1->itemAt(i);
if (btn->isChecked())
{
QPushButton* newBtn = new QPushButton;
newBtn->setText(btn->text());
layout2->addWidget(newBtn);
}
}
If you don't need to create and delete new buttons again and again, you can have constant set of buttons and just show and hide them.

Resources