1

私は QT を使用しており、ウィジェットで満たされたベクターと QVBoxLayout があります。両方を Button で埋めることは問題Addありませんが、それらを削除すると実際には機能しません。

ウィジェットを最後から最初に削除すると、すべて正常に機能しますが、他の方法でウィジェットを削除しようとすると、すべてが失敗します。多分誰かがアイデアを持っていますか?

void listwindow::remove_entry()
{
 vector<todo_list_entry *>::iterator pos;

 int i=0;
 for (pos=list_entrys_vector.begin();pos<=list_entrys_vector.end();pos++)
 {
  if((**pos).check_delete()==true)
  {
   listenLayout->removeWidget(*pos);
   listenLayout->update();
   list_entrys_vector.erase(pos);
   delete list_entrys_vector[i];
   break;
  }
  i++;
 }
} 
4

2 に答える 2

0

eraseベクターの反復処理中にベクターの要素を使用することによるイテレーターの無効化に問題がある可能性があります。一度実行するとlist_entrys_vector.erase(pos)posは有効なイテレータではなくなるため、次にループで使用しようとすると、問題が発生します。反復中にベクターの個々の要素に対して消去を使用する代わりに、最後まで待って、 を使用して一度にすべて消去しますlist_entrys_vector.clear()

または、すべてのエントリを削除したくない場合は、remove_ifと then を組み合わせて削除しますerasefエントリを受け取り、削除する必要があるかどうかを返す関数の場合true、これを行うことができます。

pos = std::remove_if(list_entrys_vector.begin(),list_entrys_vector.end(),f);

ここで、削除するエントリはベクトルの最後にあり、pos は削除する必要がある最初のエントリを指します。その後、これらのエントリに対して他のことを行うことができます。

list_entrys_vector.erase(pos,list_entrys_vector.end());

これを実現する方法は他にもありますが、覚えておくべき重要な点は、反復処理中にベクターから要素を消去できないことです。それをしたい場合は、のようなものを使用する必要がありますstd::list

于 2012-10-24T19:07:01.177 に答える
0

私はそれをこれに変更しましたが、今ではベクトル消去が正常に機能しているように見えますが、listenLayout で問題が発生します... 4 つの要素を追加して最初の要素を削除すると、3 と 4 しか表示されず、4 を削除した後に 2 が表示されます突然現れる…

void listwindow::remove_entry()
{
 vector<todo_list_entry *> buffer_vector;
 vector<todo_list_entry *>::iterator pos;


 for ( pos = list_entrys_vector.begin(); pos != list_entrys_vector.end(); ) {
    if((**pos).check_delete()==true) {
       delete * pos;
       pos = list_entrys_vector.erase(pos);
       listenLayout->removeWidget(*pos);
       listenLayout->update;
    }
    else {
       ++pos;
    }
 }

編集:順序を変更しました(最初にremoveWidget、次に削除)今ではすべてうまくいきます!

于 2012-10-25T13:58:40.837 に答える