Any regular process (including a GUI one) can declare itself a session leader (for example in python via
os.setpgrp()) and by default its children spawned after that moment (and all their descendants) will belong to its new session group, not its original one (except, of course, those which themselves become session leaders). The pgid of the new session group is typically (or always, not 100% sure) the pid of the self-proclaimed session leader process.
Here's an actual example:
$ ps -eo pid,ppid,pgid,tty,cmd | egrep "(PPID|konsole|Running)"
PID PPID PGID TT CMD
4841 9633 4840 pts/3 grep -E (PPID|konsole|Running)
7375 1 7374 pts/3 konsole -p name=ROOT -e su -
9373 1 9373 ? kdeinit4: kdeinit4 Running...
9489 1 9373 ? kdeinit4: konsole [kdeinit] -session 102172181df177000142160830700000083410009_14428560
9492 1 9373 ? kdeinit4: konsole [kdeinit] -session 102172181df177000142901958900000018140011_14428560
9558 1 9373 ? kdeinit4: konsole [kdeinit] -session 102112051ed1c6000144239124800000016680010_14428560
konsole processes listed are started by KDE itself, via
kdeinit (pid 9373) and inherit its pgid 9373.
konsole pid 7375 (displayed on the same display and controlled by KDE just as the rest of the GUI apps) was started manually from the shell running in one of the other
konsole processes. It belongs to pgid 7374 started when this
konsole process itself was forked (by its parent pid 7374, now defunct, which became session leader at the time).
Unrelated to the controlling terminal (each of the shells inside those konsole processes has its own tty, for example, but only the manually-started konsole process has one - pty/3, inherited from its ancestor shell, the KDE-started
konsoles don't have a tty).
Side note: pid == pgid == 9373 indicates 9373 is a self-proclaimed session leader process as well.