Comparing event loop to system calls, is similar to comparing apples to.... cars and not just orange cars.
System calls are used as part of your normal, structured control flow. You do X, Y, system call then Z. As you pointed out, the purpose of system calls is to give your app to subsystems which are managed by the kernel. Since those subsystems are shared/accessed by multiple processes, you must cross the boundary from user into kernel space in order to work with them.
Event loops, on the other hand live completely in your user space. They are the basis of an Event Driven Programming (EDP), which is very common GUI applications but also has uses in many other areas. Instead of having one control structure that does "X, Y, sleep, Z, system call..." in EDP you define small snippets of code (i.e. event handlers) and their job is to respond to particular events. Event loop is what dispatches those events to their respective handlers, at the most basic level, it is nothing more than a queue and a lookup table with function pointers.
Since GUI applications are by their nature event driven (i.e. user clicks here and there), event loops are just about universally used to drive them. One reason for using events in a GUI is let's say you want something to blink every 2 seconds. If you had a non-GUI app, you could implement a simple loop with sleep(2), but if you call sleep() in a GUI, your application would freeze since the loop would no longer respond to mouse/keyboard clicks from the user. The way around it, would be to create a timer that fires an event every 2 seconds. This way the loop will continue to dispatch all other events and every 2 minutes your timer handler would be invoked to change the color of whatever it is you are blinking.
To clarify what an event loop is (in pseudo code):
while(true) {
event = GetEvent() // will sleep until next event arrives
DispatchEvent(event)
}
This can run on just about any thread, but would typically be on the main one that started the app. Inside DispatchEvent, you simply have a lookup map, that maps event types (e.g. an int) to one or more event handlers (function pointer, interfaces pointers... etc) registered to listen for that event.