PDA

View Full Version : trying to get a QIcon into the center of a QTableWidgetItem



StephenHazel
21st October 2021, 01:20
icons seem to only show up on the left within the item.

I've tried overriding paint() within my attached QStyledItemDelegate derived class, but it still only shows on the left.

Within my table, when a column is showing an icon, I need it to occupy the center of the whole QTableWidgetItem (cell).

Below is my, uhhh, not very pretty code.

My main code populating the table has a callback func to populate QComboBoxs and other stuff.
QComboBoxes are the main reason I add the SIDlg class derived from QStyledItemDelegate.

I -think- It's just the paint() method within class SIDlg that needs some work.
But I don't know how to get the whole rectangle (I think that's the problem??)



// Populating table:

// my main window class has a
CtlTabl _tr;

// window class init function has this hooking design time tr which is a QTableWidget
// column headers in a zz string
// * prefix means show an icon. _ prefix for edited column. ^ prefix means QComboBox edited > means right justified
_tr.Init (ui->tr,
"*Lrn\0"
"*^Hand\0"
"_Track\0"
"^SoundDir\0"
"^Sound\0"
"Dev.Chan\0"
"Mix\0"
">Notes\0"
">Ctrls\0", TrPop);
_tr.SetRowH (Up.txH - 4);

ui->tr->setContextMenuPolicy (Qt::CustomContextMenu);
connect (ui->tr, & QTableWidget::itemClicked, this, & PCheetah::TrClk);
connect (ui->tr, & QTableWidget::customContextMenuRequested,
this, & PCheetah::TrClkR);
connect (ui->tr, & QTableWidget::itemChanged, this, & PCheetah::TrUpd);


// Then populated as:

char *rp [32];
_tr.Open ();
for (ubyte i = 0, tc = 0; i < Up.rTrk; i++) {
rp [0] = Up.trk [i].lrn; rp [1] = Up.trk [i].ez;
rp [2] = Up.trk [i].name; rp [3] = Up.trk [i].grp;
rp [4] = Up.trk [i].snd; rp [5] = Up.trk [i].dev;
rp [6] = CC(""); rp [7] = Up.trk [i].notes;
rp [8] = Up.trk [i].ctrls; rp [9] = nullptr;
_tr.Put (rp);
if (Cfg.ntCo == 2) { // color by track
if ((rp [0][0] == 'l') || (rp [1][0] == 'S'))
_tr.SetColor (i, CMap (tc++));
}
else {
switch (rp [1][0]) {
case 'L': tc = 0; break;
case 'R': tc = 1; break;
default: tc = 9;
}
if (tc < 2) _tr.SetColor (i, CTnt [tc]);
}

}
_tr.Shut (); _tr.HopTo (Up.eTrk, 0);




typedef void (*ppop)(char *ls, ubyt2 r, ubyte c);

class SIDlg: public QStyledItemDelegate {
Q_OBJECT
private:
char *_ed;
ppop _pop;
QTableWidget *_tbl;

public:
SIDlg (QObject *par, char *ed, ppop pop);
~SIDlg () {}
void paint (QPainter *p, const QStyleOptionViewItem &opt,
const QModelIndex &ind) const override;
QWidget *createEditor (QWidget *tb, const QStyleOptionViewItem &opt,
const QModelIndex &ind) const override;
void setEditorData (QWidget *ed, const QModelIndex &ind) const override;
void setModelData (QWidget *ed, QAbstractItemModel *mod,
const QModelIndex &ind) const override;
public slots:
void cbChanged (int i);
};


class CtlTabl {
public:
CtlTabl () {_t = nullptr; _nr = _tr = _ih = _tc = 0;}
~CtlTabl () {}

// hdr is zz string of labels
// >| prefix means right or center just
// _^ prefix means string or combo edit
void Init (QTableWidget *t, const char *hdr, ppop pop = nullptr);
void SetRowH (ubyt2 h);
ubyt2 ColW (ubyte c);
void SetColW (ubyte c, ubyt2 w);
ubyt2 NRow ();
ubyte NCol ();
ubyt2 CurRow ();
ubyte CurCol ();
char *Get (ubyt2 r, ubyte c);
void Set (ubyt2 r, ubyte c, char *s);
void HopTo (ubyt2 r, ubyte c);
void SetColor (ubyt2 r, QColor c);

void Open ();
void Put (char **rp);
void Shut ();

private:
QTableWidget *_t;
char _ju [40];
char _ed [40];
ubyt2 _nr, _tr, _ih;
ubyte _tc;
};


SIDlg::SIDlg (QObject *par, char *ed, ppop pop)
: QStyledItemDelegate (par)
{ _ed = ed; _pop = pop; }

void SIDlg::paint (QPainter *p, const QStyleOptionViewItem &opt,
const QModelIndex &ind) const
{ if (! opt.icon.isNull ())
{p->save (); opt.icon.paint (p, opt.rect);
p->restore ();}
else QStyledItemDelegate::paint (p, opt, ind);
}

void SIDlg::cbChanged (int i)
{ QComboBox *cb = qobject_cast<QComboBox *>(sender ());
(void)i; emit commitData (cb); emit closeEditor (cb);
}

QWidget *SIDlg::createEditor (QWidget *par, const QStyleOptionViewItem &opt,
const QModelIndex &ind) const
{ BStr bs;
char *s;
if (_ed [ind.column ()] == '^') {
_pop (bs, ind.row (), ind.column ());
if (*bs == 0) return nullptr;

QComboBox *cb = new QComboBox (par);
for (s = bs; *s; s = & s [StrLn (s)+1])
cb->addItem (StrCm (s, CC("-")) ? s : "");
return cb;
}
return QStyledItemDelegate::createEditor (par, opt, ind);
}

void SIDlg::setEditorData (QWidget *ed, const QModelIndex &ind) const
{ QComboBox *cb = qobject_cast<QComboBox *>(ed);
if (cb) {
int i = cb->findText (ind.data (Qt::EditRole).toString ());
if (i < 0) i = 0;
cb->setCurrentIndex (i); cb->showPopup ();
connect (cb, & QComboBox::currentIndexChanged,
this, & SIDlg::cbChanged);
}
else QStyledItemDelegate::setEditorData (ed, ind);
}

void SIDlg::setModelData (QWidget *ed, QAbstractItemModel *mod,
const QModelIndex &ind) const
{ QComboBox *cb = qobject_cast<QComboBox *>(ed);
if (cb) mod->setData (ind, cb->currentText (), Qt::EditRole);
else QStyledItemDelegate::setModelData (ed, mod, ind);
}


void CtlTabl::Init (QTableWidget *t, const char *hdr, ppop pop)
// hdr is zz string of labels
// * prefix means icon
// >| prefix means right or center just
// _^ prefix means string or combo edit
{ ubyte c;
char *h;
char ed = '\0'; // _ means editing, ^ means QComboBox so delegate too
QStringList sl;
_t = t;
for (c = 0, h = CC(hdr); *h; c++, h = & h [StrLn (h)+1]) {
_ju [c] = _ed [c] = '\0';
if ((*h == '*') || (*h == '>') || (*h== '|')) _ju [c] = *h++;
if (*h == '_') {_ed [c] = *h++; if (ed != '^') ed = '_';}
if (*h == '^') _ed [c] = ed = *h++;
sl << QString::fromStdString (h);
}
_t->horizontalHeader ()->setSectionResizeMode (
QHeaderView::ResizeToContents);
_t->setColumnCount (c); _t->setHorizontalHeaderLabels (sl);
_t->verticalHeader ()->hide ();
_t->setAlternatingRowColors (false);
if (ed == '^') _t->setItemDelegate (new SIDlg (_t, _ed, pop));
_t->setEditTriggers (ed ? QAbstractItemView::AllEditTriggers
: QAbstractItemView::NoEditTriggers);
_t->setSelectionBehavior (QAbstractItemView::SelectRows);
}

/* _t->horizontalHeader ()->setSectionResizeMode (2, QHeaderView::Fixed)
** _t->horizontalHeader ()->setStretchLastSection (true);
** _t->horizontalHeader ()->setHighlightSections (false);
** _t->setSelectionBehavior (QAbstractItemView::SelectItems/Rows);
** _t->setSelectionMode (QAbstractItemView::ExtendedSelection);
** _t->setGridShow (false);
*/

void CtlTabl::SetRowH (ubyt2 h)
{ _t->verticalHeader ()->setDefaultSectionSize (h);
_t->setIconSize (QSize (h, h));
_ih = h;
}

ubyt2 CtlTabl::ColW (ubyte c) {return _t->columnWidth (c);}
void CtlTabl::SetColW (ubyte c, ubyt2 w)
{ _t->horizontalHeader ()->setSectionResizeMode (c, QHeaderView::Fixed);
_t->setColumnWidth (c, w);
}

ubyt2 CtlTabl::NRow () {return _t->rowCount ();}
ubyte CtlTabl::NCol () {return _t->columnCount ();}
ubyt2 CtlTabl::CurRow () {return _t->currentRow ();}
ubyte CtlTabl::CurCol () {return _t->currentColumn ();}
char *CtlTabl::Get (ubyt2 r, ubyte c) {return UnQS (_t->item (r, c)->text ());}

// clip cuz too many chars to post

void CtlTabl::Open ()
{ _tr = CurRow (); _tc = CurCol ();
_t->hide (); _t->blockSignals (true);
_t->clearContents (); _t->setRowCount (0);
_nr = 0;
}

void CtlTabl::Put (char **rp)
{ ubyte c;
TStr ico;
QTableWidgetItem *it;
_t->setRowCount (_nr+1);
for (c = 0; *rp; c++, rp++) {
if (! (it = _t->item (_nr, c)))
_t->setItem (_nr, c, it = new QTableWidgetItem);
if (_ed [c]) it->setFlags (it->flags () | Qt::ItemIsEditable);
else it->setFlags (it->flags () & ~Qt::ItemIsEditable);
if (_ju [c] == '*') {
if (**rp) {
if (**rp == '*') it->setText (++(*rp));
else if (**rp) it->setIcon (QIcon (StrFmt (ico,
":/tico/`s", *rp)));
else it->setIcon (QIcon ());
}
}
else {
if (_ju [c] == '>') it->setTextAlignment (Qt::AlignRight);
if (_ju [c] == '|') it->setTextAlignment (Qt::AlignCenter);
it->setText (*rp);
}
}
_nr++;
}

void CtlTabl::Shut ()
{ _t->show (); _t->blockSignals (false); HopTo (_tr, _tc); }