我找到了一個解決方案,但它有點哈克。該QWidget::setTabOrder
將不允許鏈上的小部件本身,所以這種方法也無濟於事(即使你使用的焦點代理)
但是,您可以定義一個「焦點轉發」:
class FocusForwarder : public QWidget
{
public:
explicit FocusForwarder(QWidget *proxy) :
QWidget((QWidget *) proxy->parent()),
m_proxy(proxy)
{
setFocusPolicy(Qt::TabFocus);
}
protected:
void focusInEvent(QFocusEvent *) {
m_proxy->setFocus();
}
private:
QWidget *m_proxy;
};
而在開始和你末尾添加它們鏈條:
FocusForwarder *w1 = new FocusForwarder(ui->bA);
FocusForwarder *w2 = new FocusForwarder(ui->bD);
QWidget::setTabOrder(w1, ui->bA);
QWidget::setTabOrder(ui->bA, ui->bB);
QWidget::setTabOrder(ui->bB, ui->bC);
QWidget::setTabOrder(ui->bC, ui->bD);
QWidget::setTabOrder(ui->bD, w2);
詳細
對於setTabOrder
工作,小部件必須在同一窗口。爲了確保這一點,轉發器被放置在代理的父代(在初始化程序列表中)。
對於這種機制,焦點方向(Tab或Shit + Tab)無關緊要。只要FocusFowarder獲得焦點,它就會「轉發」它的代理。 方向由Qt在內部處理。你只需在你的連鎖店中添加「哨兵」。
使用在QtDesigner
當你想在QtDesigner使用它,你會創建一個Widget,並促進它的轉發器。正如你不能直接設置代理,你可以添加一個動態屬性爲代理的名稱,就像這樣:
class FocusForwarderDesigner : public QWidget
{
Q_OBJECT
Q_PROPERTY(QString proxyName READ proxyName WRITE setProxyName)
public:
QString proxyName() {
return (m_proxy) ? m_proxy->objectName() : QString::null;
}
void setProxyName(QString name) {
m_proxy = parent()->findChild<QWidget *>(name);
}
explicit FocusForwarderDesigner(QWidget *parent = NULL) :
QWidget(parent) {}
protected:
void focusInEvent(QFocusEvent *) {
if (m_proxy) m_proxy->setFocus();
}
private:
QWidget *m_proxy;
}
在設計中,可以添加一個字符串屬性名稱爲proxyName
並將其設置爲代理服務器的名稱。不要忘記在設計器中將focus policy
設置爲Tab Focus
。
你試過'QWidget :: setTabOrder(D,D)'? –
補充:http://doc.qt.io/qt-5/qwidget.html#setTabOrder – ManuelH
@king_nak:這似乎是一個好主意。我報告,如果它的工作結束:-) – FrozenTarzan