Most likely not.
It is certainly possible to write a template template <class Func1, class Func2> void waitForTimeout(QObject* sender, Func1 signal, Func2 predicate, int msec) and call it with waitForTimeout(this, &MyClass::triggered, [&](int i){...}, msTimeout);.
However, the predicate cannot reference the loop because it cannot capture it. Possibly there is a workaround that you could also provide an additional signal which will be connected to loop.quit(). This signal could be captured by your predicate lambda and thus emitted.
Another approach could be to make it a class waitForTimeout_t. Then I would probably store the predicate as a std::function. This would allow a 2-step approach with a constructor and member functions:
waitForTimeout_t waiter(this, &MyClass::triggered, [&](int i) {}, msTimeout); // just a dummy lambda to get the type right for std::function
waiter.setPrecidate([&](int i) { if(i == 123) waiter.getLoop().quit(); });
waiter.wait();
In simple cases you could directly write:
waitForTimeout_t(this, &MyClass::triggered, [&](int i) {...}, msTimeout).wait();
It would be little annoying to always have to write wait(), though.
One other disadvantage would be that I would assume that the last few lines (if(time.isActive())...) would be per specific use cases. With my first suggestion the template function waitForTimeout(...) could just return a bool which tells you if the timer did fire.
The thing is that this approach should not be your goto solution. Nested loops are considered evil in Qt. Nothing is preventing you from becoming deeply nested. Qt documentation itself discourages using nested loops. They should be rarely used. Thus, it is best to not write a template for this because it would encourage using this approach.