簡體   English   中英

延遲發射信號

[英]emit signal with delay

我想要實現的目標是發出一個信號,但在實際發出之前將其延遲一段時間。

我的想法是這樣的:

emitLater(QObject *obj, QEvent *event, int msDelay)
{
    QTimer...
    connect(timout to obj and event...
    start timer with msDelay...

    //maybe I might need a public timer of some sort but the idea is clear
}

因此,此方法因QEvent參數而失敗,因為 Signals 無法轉換為QEvents

我嘗試使用 std::bind 進行幾種變體調用,但無法正常工作:

//the call
std::function<void(void)> signal = std::bind(&CustomPushButton_Header::clicked, &uiWindow->btnHeader_left); //just a random button to connect a valid signal
emitLater(signal, 2000);

//the function
emitLater(std::function<void(void)>, int msDelay)
{
    qDebug() << "hi";
}

我希望有一個適用於所有對象和所有信號的解決方案......也許只有調用 function 的部分。 我認為延遲會很容易。

或者你有一個不同的甚至更簡單的方法。 那樣就好了。

我查看的一些來源:

有一個 function QTimer::singleShot()可以在一定時間后觸發信號/插槽。 我是這樣實現的:

void MyWindow::emitLater(const QObject *obj, const char *signalOrSlot, int msDelay)
{
    //use QTimer::singleShot() to trigger the signal/slot after a certain amount of time
    QTimer::singleShot(msDelay, obj, signalOrSlot);
}

並像這樣使用它:

void MyWindow::on_pushButton_5_clicked()
{
    //trigger the "doing fancy stuff" function after 5 seconds (= 5000 ms)
    emitLater(this, SLOT(setText()), 5000);
}

void MyWindow::setText()
{
    //do some fancy stuff
    ui->label_3->setText("Hello World!");
}

另一種選擇是來自 ΦXocę 웃 Пepeúpa ツ 的答案,並使用 lambda 表達式作為QTimer::timout()信號的調用 function :

void MyWindow::on_pushButton_5_clicked()
{
    //initialize timer
    QTimer* t= new QTimer(this);
    t->setSingleShot(true);

    //do some fancy stuff after timeout
    connect(t, &QTimer::timeout, [this]()
    {
        ui->label_3->setText("Hello World!");
    });

    //start the timer with delay of 5 seconds (= 5000 ms)
    t->start(5000);
}

您可以為此使用計時器,在上面的示例中,您對按鈕中的單擊槽做出反應,定義一個 QTimer,連接超時時調用的內容(在這種情況下是 lambda),然后啟動計時器:)

void MyWindow::on_pushButton_5_clicked()
{
    QTimer* t= new QTimer(this);
    connect(t, &QTimer::timeout, [this](){ui->label_3->setText("done!");});
    t->start(5000); //after 5 seconds
}

這是我在Python中使用PySide2的實現。

首先,我創建了一個 class:

class DelayedSignal:
    def __init__(self, timeout, func):
        self.timeout = timeout
        self.func = func
        self.timer = QTimer()
        self.timer.setSingleShot(True)
        self.timer.setInterval(1000 * timeout)
        self.timer.timeout.connect(func)

    @Slot()
    def __call__(self):
        self.timer.stop()
        self.timer.start()

這是代碼的 rest,因此所有這些都是最小的工作示例:

from PySide2.QtCore import QTimer, Slot
from PySide2.QtWidgets import QPushButton, QWidget, QHBoxLayout


class AppWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.btn = QPushButton("PRESS", self)
        self.setLayout(QHBoxLayout())
        self.layout().addWidget(self.btn)
        self.delayed_signal = DelayedSignal(timeout=2, func=self.target)
        self.btn.clicked.connect(self.delayed_signal)

    @Slot()
    def target(self):
        print("END")


if __name__ == '__main__':
    import sys

    from PySide2.QtWidgets import QApplication

    app = QApplication(sys.argv)
    window = AppWindow()
    window.show()
    sys.exit(app.exec_())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM