問題描述
我有乙個單例項的qaction
的集合actions_
然後傳入不同的q*******
進行新增到不同的q*******
例項中。其中使用到了qactiongroup
將其中的單個qaction
進行互斥的處理。當建立了多個q*******例項後,釋放了其中乙個例項,其他q*******
的qactiongroup
互斥就不生效了。
之前的實現方式
action_group_ = new qactiongroup(*******_);
*******_->addaction(action_group_->addaction(actions_->get(action_id_t::control_mouse)));
*******_->addaction(action_group_->addaction(actions_->get(action_id_t::control_marker)));
*******_->addaction(action_group_->addaction(actions_->get(action_id_t::control_bandpower)));
actions_->get(action_id_t::control_mouse)->setchecked(true);
原因分析:
action_group_->addaction(actions_->get(action_id_t::control_mouse)) 會生成乙個新的qaction
取名為temp_action,當q*******被釋放的時候,action_group_也被釋放了,同時temp_action也被釋放了,此時導致 actions_->get(action_id_t::control_mouse))qaction
中的互斥屬性就被釋放掉了。(具體的原因看後面的原始碼分析就可以理解了)
解決方案
在建立的時候就將qactiongroup
的action
建立出來,並用集合管理起來。問題就得到了解決。
//建立
control_group_ = new qactiongroup(this);
id_2_action_group_[action_id_t::control_strat] = control_group_->addaction(get(action_id_t::control_strat));
id_2_action_group_[action_id_t::control_pause] = control_group_->addaction(get(action_id_t::control_pause));
action_group_ = new qactiongroup(this);
id_2_action_group_[action_id_t::control_mouse] = action_group_->addaction(get(action_id_t::control_mouse));
id_2_action_group_[action_id_t::control_marker] = action_group_->addaction(get(action_id_t::control_marker));
id_2_action_group_[action_id_t::control_bandpower] = action_group_->addaction(get(action_id_t::control_bandpower));
get(action_id_t::control_mouse)->setchecked(true);
//呼叫
*******_->addaction(actions_->get_group(action_id_t::control_mouse));
*******_->addaction(actions_->get_group(action_id_t::control_marker));
*******_->addaction(actions_->get_group(action_id_t::control_bandpower));
原始碼分析,找到問題的本質
下面值列舉了關鍵的**用於分析:
//addaction方法
qaction *qactiongroup::addaction(qaction* a)
if(!a->d_func()->forcedisabled)
if(!a->d_func()->forceinvisible)
if(a->ischecked())
d->current = a;
qactiongroup *oldgroup = a->d_func()->group;
//並且從老的group中移動出來,永遠儲存的只有最後建立出來的qactiongroup 對qaction的管理是有效的
if(oldgroup != this)
return a;
}//槽函式
//當某個qaction的的狀態改變時候,槽函式就是將其他的checked狀態設定成為false
//所以出現bug原因就被找到了
void qactiongroupprivate::_q_actionchanged()
} else if (action == current)
}}
不互斥的列舉
假設我有乙個列舉類,這個列舉類用來修飾乙個類的各種屬性,列舉並不互斥,可以協同修飾乙個類。或者說這個列舉用於表明這個類的各個狀態。可以將這個狀態標記為on或off。假設我有乙個列舉buff public enum buff 以上的列舉代表了三種不同的增益,用16進製制int型別表示。定義了乙個列舉組...
執行緒同步與互斥 互斥鎖
在多工作業系統中,同時執行的多個任務可能都需要使用同一種資源。這個過程有點類似於,公司部門裡,我在使用著印表機列印東西的同時 還沒有列印完 別人剛好也在此刻使用印表機列印東西,如果不做任何處理的話,列印出來的東西肯定是錯亂的。下面我們用程式模擬一下這個過程,執行緒一需要列印 hello 執行緒二需要...
執行緒同步與互斥 互斥鎖
在多工作業系統中,同時執行的多個任務可能都需要使用同一種資源。這個過程有點類似於,公司部門裡,我在使用著印表機列印東西的同時 還沒有列印完 別人剛好也在此刻使用印表機列印東西,如果不做任何處理的話,列印出來的東西肯定是錯亂的。下面我們用程式模擬一下這個過程,執行緒一需要列印 hello 執行緒二需要...