2016-12-06 8 views
0

믹스 라인과 유사한 프록시 모델 (Qt5)을 작성하여 다른 프록시 모델에 추가 첫 번째 컬럼을 추가하여 각 행에 조치의 QToolBar을 추가했습니다. 테이블 뷰 (예 : "삭제"버튼). 이 모델은 첫 번째 열에 QList<QVariant>을 채우는 방법을 제공합니다. 대리인은 각 QVariant (일반적으로 int s/enum)의 의미가 무엇인지 알아야하며 그에 따라 QToolBar을 채 웁니다. 마지막 기능으로 동작이 없으면 추가 열이 추가되지 않습니다 (이 경우 QIdentityProxyModel처럼 동작 함). 일단 추가되면 조치를 제거 할 수 없습니다. 그것은 다른 날을위한 특징입니다.컬럼을 추가하기위한 QAbstractProxyModel 특화 : 테이블 셀이 비어 짐

오늘날 문제는 뷰에 모델을 설정하기 전에 작업을 삽입 할 때 셀이 모두 공백이라는 것입니다. 그래서, 신호 또는 사람 (필자는 조각의 말에 실수가 add_action 기능에 생각) 무엇으로 알고 뭔가 잘못하고 있어요 : 설정 작업없이

template<class proxy_model> 
class action_model : public proxy_model 
{ 
    QList<QVariant> l_actions; 

public: 
    using base_t = proxy_model; 
    using base_t::base_t; // Inheriting constructors. 

    QModelIndex mapFromSource(const QModelIndex& source_idx) const override 
    { 
     if (!l_actions.empty() and source_idx.isValid()) 
      return this->createIndex(source_idx.row(), 
            source_idx.column() + 1); 
     else // identity proxy case 
      return base_t::mapFromSource(source_idx); 
    } // same for mapToSource but with - 1 instead of + 1. 

    int columnCount(const QModelIndex& parent = QModelIndex()) const override 
    { return this->base_t::columnCount() + !l_actions.empty(); } 

    QVariant headerData(int section, Qt::Orientation orientation, int role) const override 
    { 
     if (!l_actions.empty()) { 

      if (orientation == Qt::Horizontal and section == 0 
       and role == Qt::DisplayRole) 
       return "Actions"; // Testing. 
      else 
       return base_t::headerData(section - 1, orientation, role); 

     } else // identity proxy case 
      return base_t::headerData(section, orientation, role); 
    } 

    QVariant data(const QModelIndex& idx, int role) const override 
    { 
     if (!l_actions.empty()) { 
      if (idx.column() == 0 and role = Qt::DisplayRole) 
       return l_actions; // All the actions for drawing. 
      else 
       return QVariant(); 
     } else // identity proxy case 
      return base_t::data(idx, role); 
    } 

    Qt::ItemFlags flags(QModelIndex const& idx) const 
    { 
     if (!l_actions.empty() and idx.column() == 0) 
      return Qt::NoItemFlags; // No editable or selectable 
     else 
      return base_t::flags(idx); 
    } 

    // And here, I think, is where the fun starts: 
    // The action could be added before or after the sourceModel 
    // is set or this model is connected to a view, but I don't 
    // how that cases are supposed to be managed. 
    void add_action(QVariant const& action) 
    { 
     bool was_empty = l_actions.empty(); 
     l_actions << action; 

     if (was_empty and !this->insertColumns(0, 1)) 
      throw std::logic_error("Something went wrong"); 

     Q_EMIT this->dataChanged 
      (this->createIndex(0, 0), 
       this->createIndex(this->rowCount(), 0), 
       { Qt::DisplayRole }); 
    } 

}; 

을,이 모델은 잘 작동 , QAbstractIdentityProxyModelQSortFilterProxyModel 모두 proxy_model으로 표시됩니다. 그러나 작업을 설정하면보기에 QSortFilterProxyModelQAbstractIdentityProxyModel을 포함한 모든 셀 공백이 표시됩니다. 나는 아무도를 설정하지 않았기 때문에

enum sql_action { DELETE }; 

auto* table_model = /* My QSqlTableModel */; 
auto* view_model = new action_model<QIdentityProxyModel>(my_parent); 
auto* table_view = new QTableView; 

view_model->add_action(static_cast<int>(sql_action::DELETE)); 
view_model->setSourceModel(table_model); 

table_view->setModel(view_model); 
table_view->setSortingEnabled(true); 
table_view->setAlternatingRowColors(true); 
// The last column is printed in white, not with alternate colors. 

table_view->show(); 
table_model->select(); 

대의원은 문제가되지 않습니다 : 여기에

는 사용자 영역 코드입니다. 나는 흰 칸이있는 첫 번째 칼럼을 기대하지만, 전적으로 흰 식탁을 얻는다. 마지막 열 이름을 제외한 열 이름이 잘 표시되어 열 이름으로 0 만 인쇄됩니다.

내가 뭘 잘못하고 있니?

+0

을 반환 누락'mapToSource()' . 'columnCount()'의 코드도 이상적이지 않습니다. 'true'는 1이고 다른 0이 아닌 값은 0이 아닙니다. –

+0

'mapToSource'는 질문을 짧게하기 위해'mapFromSource' 바로 아래에 주석 처리되어 있습니다 (사실상 동일). 'columnCount'는 같은 이유로 단축됩니다. 내 코드에서는 변환없이 'if'를 사용합니다. 어쨌든'emtpy'는'bool'을 리턴하고, 표준은'false' 부울 값이'int''에'cast'되고'true'에'1'을 던진다는 것을 보증합니다. 그래서, 나는 코드가 정확하고 표준에 순응한다고 생각합니다. 어쨌든, 문제는 다른 곳에 있어야합니다. –

+0

흠, 물론, 나는 정수에 부울을 추가하는 것이 이상하다고 생각합니다. –

답변

0

문제는 data() 방법에 있습니다.

  1. 당신은 Qt::DisplayRolerole 당신이 역할
  2. 에 할당 비교하지 않는 경우이 작업을하면 어느 작업 항목이나 QVariant(), 결코 어쩌면 모든 데이터