Seite 1 von 1

[gelöst] CheckBox in einem TableView

Verfasst: 24. November 2008 20:25
von MiKla
Ich habe hier ein Problem, wo ich schon länger nach einer sauberen Lösung suche. Ich habe ein QTableView mit eigenem Model und eigenem Delegate.
In der ersten Spalte will ich permanent eine Checkbox anzeigen, die man natürlich auch schalten kann. Das anzeigen der Checkbox, permanent, ist kein Problem:

Code: Alles auswählen

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option);
     switch(index.column()){
       case 0:{         
         QStyleOptionButton newopt;
         newopt.rect = opt.rect;
         newopt.palette = opt.palette;
         newopt.palette.setColor(QPalette::ButtonText, QColor(Qt::black));
         if (index.data().toBool())
            newopt.state |= QStyle::State_On;
         QApplication::style()->drawControl(QStyle::CE_CheckBox, &newopt, painter);
...
}

QWidget *MyDelegate::createEditor(QWidget *parent,
    const QStyleOptionViewItem &option ,
    const QModelIndex & index ) const
{
    switch(index.column())
    {
        case 0:
        {
            QCheckBox *checkBox = new QCheckBox(parent);
            //checkBox->setLayoutDirection(Qt::RightToLeft);
            return checkBox;
        ...
        }
Das Problem ist, das wenn der Editor aufgeht die Checkbox in der Mitte erscheint, die permanente Checkbox aber linksbündig ist und somit die Checkbox "springt". Mit :

Code: Alles auswählen

newopt.direction = Qt::RightToLeft;
im paint und

Code: Alles auswählen

checkBox->setLayoutDirection(Qt::RightToLeft);
im createEditor, hab ich alles rechtsbündig und es springt nichts.
Aber ich hätte es gern zentriert! Ich habe leider keine Idee mehr, wie ich das hin bekomme! Wenn von Euch jemand eine Idee hätte wäre ich sehr dankbar!!!

Verfasst: 25. November 2008 09:09
von upsala
Verwende keine QCheckBox sondern mache alles komplett selber, vor allem schau mal in den Sourcen von Qt nach.

[gelöst] CheckBox in einem TableView

Verfasst: 25. November 2008 14:40
von MiKla
Ich habe mir sowas schon gedacht! Ich habe gehofft, dass es einen einfacheren Weg gibt.

Falls es jemanden interessiert hier meine Lösung:
im Delegate:

Code: Alles auswählen

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
    QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option);
     switch(index.column()){
       case 0:{         
		   if (index.data().toBool()){
				static bool once=false;
				QRect r(opt.rect.x()+ opt.rect.width()/2-5, opt.rect.y()+ opt.rect.height()/2-5, 10, 10);
				QPen pen, pen_save;
				if(!once){
					pen_save=painter->pen();
					once=true;
				}
				pen.setColor(Qt::gray);
				//painter->fillRect(r, opt.palette.brush(QPalette::Button));
				painter->setPen(pen);
				painter->drawRoundRect(r);
				switch(index.row())
				{
						case 0:     pen.setColor(Qt::blue);
									break;
						case 1:     pen.setColor(Qt::red);
									break;
						case 2:     pen.setColor(Qt::green);
									break;
						case 3:     pen.setColor(Qt::yellow);
									break;
						case 4:     pen.setColor(Qt::darkGreen);
									break;
						case 5:     pen.setColor(Qt::magenta);
									break;
						case 6:     pen.setColor(Qt::gray);
									break;
						case 7:     pen.setColor(Qt::cyan);
									break;
				}
				pen.setWidth(pen_save.width()+2);
				painter->setPen(pen);
				painter->drawLine(r.x()+3,r.y()+3,r.x()+r.width()-3,r.y()+r.height()-3);
				painter->drawLine(r.x()+r.width()-3,r.y()+3,r.x()+3,r.y()+r.height()-3);
		   }else{
				static bool once=false;
				QRect r(opt.rect.x()+ opt.rect.width()/2-5, opt.rect.y()+ opt.rect.height()/2-5, 10, 10);
				QPen pen, pen_save;
				if(!once){
					pen_save=painter->pen();
					once=true;
				}
				pen.setWidth(pen_save.width()+1);
				pen.setColor(Qt::gray);
				//painter->fillRect(r, opt.palette.brush(QPalette::Button));
				painter->setPen(pen);
				painter->drawRoundRect(r);
		   }
		   break;        
       }
       case 30:
       ....

    switch(index.column())
    {
        case 0:
        {
			return 0;//wichtig, damit keine CheckBox gezeichnet wird;
        }
        case 3:
        ...
im MainWindow:

Code: Alles auswählen

...
connect(tableView,	SIGNAL(clicked ( const QModelIndex &)), this, SLOT(tableViewClicked(const QModelIndex &)));
...

void QtTest01::tableViewClicked(const QModelIndex &index){
	if (index.isValid()){
		if (index.column()== 0)
			model->setData(index, !index.data().toBool());
	}
}
Damit funktioniert es wie ich es mir vorgestellt habe!
Vielen Dank für die Anregung!

[gelöst] CheckBox in einem TableView

Verfasst: 28. November 2008 20:07
von MiKla
Die obere Version funktioniert zwar aber so richtig gefallen hat es mir nicht. Also habe ich heute noch mal im Qt Sourcecode gesucht und bin fündig geworden. Für die, die es interessiert, hier die neue Version:

Code: Alles auswählen

void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                         const QModelIndex &index) const
{
     QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option);
     QStyleOptionButton opt1;

     switch (index.column())
     {
       case 0:
       {
            switch (index.row())
            {
                    case 0:  opt1.palette.setColor(QPalette::Text, Qt::blue);
                                break;
                    case 1:  opt1.palette.setColor(QPalette::Text, Qt::red);
                                break;
                    case 2:  opt1.palette.setColor(QPalette::Text, Qt::green);
                                break;
                    case 3:  opt1.palette.setColor(QPalette::Text, Qt::yellow);
                                break;
                    case 4:  opt1.palette.setColor(QPalette::Text, Qt::darkGreen);
                                break;
                    case 5:  opt1.palette.setColor(QPalette::Text, Qt::magenta);
                                break;
                    case 6:  opt1.palette.setColor(QPalette::Text, Qt::gray);
                                break;
                    case 7:  opt1.palette.setColor(QPalette::Text, Qt::cyan);
                                break;
            }
            opt1.state |= index.data().toBool() ? QStyle::State_On : QStyle::State_Off;
            const QStyle *style = QApplication::style();
            const int indicatorWidth = style->pixelMetric(QStyle::PM_IndicatorWidth, &opt);
            const int indicatorHeight = style->pixelMetric(QStyle::PM_IndicatorHeight, &opt);
            opt1.rect = QRect(opt.rect.x()+ opt.rect.width()/2-indicatorWidth/2, 
                              opt.rect.y()+ opt.rect.height()/2-indicatorHeight/2, 
                              indicatorWidth, indicatorHeight);
            style->drawPrimitive(QStyle::PE_IndicatorCheckBox, &opt1, painter);
            break;
       }
       case 3:
       ...
Der Rest ist gleich geblieben. Diese Version gefällt mir richtig gut :lol:

Gruß Micha

Verfasst: 6. Oktober 2009 19:55
von gk_17
Moin,

ist mein erster Post hier, also nochmal hallo an alle!

Ich habe wie hier beschrieben eine Checkbox über die paint-Methode einer von QItemDelegate abgeleiteten Klasse in ein QTableView eingefügt.

Wenn ich nun mit der Maus einzelne oder alle Felder der Tabelle auswähle/markiere, werden genau die Felder mit der Checkbox nicht blau hinterlegt. Das irritiert und ich würde es gerne hinkriegen, habe nur keine Ahnung, in welcher Richtung ich suchen muss. Hat jemand einen Hinweis?

Danke,
Gernot