Kodu exe build alırken console kapatıyorum, sonradan açmam gerek ne yapabilirim

Merhaba,

Proje arayüzlü bir proje uzun süredir geliştiriyorum ve artık sıktı uğraşasım gelmiyor, eskiden önce console olarak tasarlar sonra arayüz ekler sonra programa eklerdim şimdi kolumu kaldırasım gelmiyor. Exe yaparken consoleu kapatıyorum (kapatmazsam exeyi çalıştırınca hem ui hemde console geliyor) bu yüzden arayüzü olmayan sadece console olan bir şeyi projeye ekleyince çalışsa dahi çalıştığını kullanıcı göremiyor. Console u ayrı bir Widget içinde falan farklı bir method yada kütüphane ile açmak mümkün mü ?

Kullandığım kütüphane Pyqt5

Windows’un konsolla ilginc bir iliskisi var. Bahsettiginiz ayar /subsystem:console vs /subsystem:windows link flag’i mesela. Renkler nasil calisiyor, bilmiyorum (ozel fonksiyonlari var, terminalle konusuyorlar sanirim) mesela.

Normalde konsol dedigimiz sey 0, 1 ve 2 numarali dosyalardan ibaret. (stdin, stdout, stderr) Yani programin stdout’unu nereye yonlendirirsek / 1 numarali descriptor hangi dosyaya aitse cikti oraya gidiyor. Pipe acip girdisini 1’e alip (dup2(2)) ciktisini da text widget’ina baglarsak ciktiyi orada gorebiliriz mesela.

Windows’da nasil yapiliyor bilmiyorum; zaten dedigim gibi konsolla iliskisi de biraz garip. Ama “subsystem windows” ve konsol aratilinca denenebilecek sonuclar cikiyor.

Bu arada bir subsystem windows programini terminalden acinca programin ciktisi o terminalde gorunuyor.

Şuan okey fakat çok basit bir login kodu çalıştırmaya denediğimde patlıyor ve şu hatayı veriyor;

python login.py
$ python login.py
Traceback (most recent call last):
  File "C:\Users\PC\Desktop\New folder (2)\login.py", line 22, in <module>
    login()
  File "C:\Users\PC\Desktop\New folder (2)\login.py", line 12, in login
    print("Giri\u015f Yap\u0131n".encode('utf-8').decode('utf-8'))
  File "C:\Users\PC\AppData\Local\Programs\Python\Python310\lib\encodings\cp1252.py", line 19, in encode
    return codecs.charmap_encode(input,self.errors,encoding_table)[0]
UnicodeEncodeError: 'charmap' codec can't encode character '\u015f' in position 4: character maps to <undefined>

import sys
import subprocess
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit
from PyQt5.QtGui import QTextCursor
from PyQt5.QtCore import Qt

class CommandLineWindow(QMainWindow):
    def __init__(self):
        super().__init__()

        self.init_ui()

    def init_ui(self):
        self.console = QTextEdit(self)
        self.console.setReadOnly(True)
        self.console.setStyleSheet("background-color: black; color: white;")
        self.setCentralWidget(self.console)
        self.console.setTextInteractionFlags(Qt.TextEditorInteraction)

        self.console.setPlaceholderText('Komutları buraya yazın ve Enter\'a basın...')
        self.console.installEventFilter(self)

        self.setWindowTitle('Terminal Arayüzü')
        self.setGeometry(100, 100, 800, 600)

    def eventFilter(self, obj, event):
        if obj is self.console and event.type() == event.KeyPress:
            key = event.key()
            if key == Qt.Key_Enter or key == Qt.Key_Return:
                self.process_command()
                return True
        return super().eventFilter(obj, event)

    def process_command(self):
        cursor = self.console.textCursor()
        cursor.movePosition(QTextCursor.StartOfBlock)
        command = cursor.block().text()
        cursor.removeSelectedText()
        self.console.append(f'$ {command}')

        try:
            result = subprocess.run(command, shell=True, capture_output=True, text=True)
            output = result.stdout + result.stderr
        except Exception as e:
            output = str(e)

        self.console.append(output)
        cursor.movePosition(QTextCursor.End)
        self.console.setTextCursor(cursor)
        self.console.append('')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    terminal = CommandLineWindow()
    terminal.show()
    sys.exit(app.exec_())

?


Bi de locale CP1252 gibi gozukuyor; onda ş harfi yok.

Türkçe karakterleri sildiğimde hiç hata vermeden direkt arayüz donuyor sonra yanıt vermiyor maalesef denemiştim de yazmayı unutmuşum.

Yanlış anlamadı isem. Terminal görünmesin ama terminal parametrelerine erişebileyim istiyorsunuz.

Siz kapattığınızda terminal devre dışı kalıyor olabilir. Olmayan bir şeye de erişemediğiniz için erişim sağlayamıyor olabilirsiniz.

Etrafından dolanıp deneyebilirsiniz. Terminali hide ile gizleyip arkaplanda çalışmasını sağlayabilirsiniz.

C++ How do I hide a console window on startup? - Stack Overflow

Yukarda benzer bir çözüm var.

Bu şekilde terminal görünmez ama nesne olarak hala mevcut olduğundan metotlarına erişebilirsiniz.

1 Beğeni

Bu bende calisiyor. Windows’ta nerede takiliyor?

bu attığım şekilde bendede çalışıyor fakat oluşturduğumuz console dan standart yapıda bir python dosyası çağırmaya çalışınca (standarttan kastım bir proje yani bir login projesi yada register projesi gibi çok uzun değil 20-30 satır belki ) kod yukardaki hatayı vermekte hocam. Fakat çok basit ( print(“hello”) gibi ) içinde tek satır kod olan kodları çalıştırmakta ve widget içinde çıktıyı görebilmekteyiz. Eve geçince standart olarak nitelendirdiğim login örneğinin kodunuda ekleyebilirim.

Hide deneyeceğim hocam teşekkürler.

Beklemeye yol açan komutlar, signal-slot mekanizması kullanılmadığında GUI’yi dondurabilir ve bekleme süresince ana olay döngüsü çalışmaz.

Ayrıca python3 gibi etkileşimli komutlar yeni bir alt süreç oluşturur. Bu alt süreçlerin yönetimi önemlidir, aksi takdirde GUI yanıt veremez hale gelir. Şu anki haliyle, QTextEdit, yalnızca anında sonuç döndüren ve alt süreç gerektirmeyen komutları çalıştırabilir gibi görünüyor. Yani, terminal üzerinden python3 konsoluna geçiş yapamaz ve yazdığınız yazıları python3 konsolunda çalıştıramazsınız.

python3 -c "for i in range(1000): print(i)" ifadesi çalıştırabileceğimiz bir komut iken python3 -c "input('>>> ')" ifadesi programın donmasına yol açar.

programı, program içinden python3 main.py şeklinde çalıştırabilir, ana pencerenin açılmasını sağlayabilirsiniz. Ancak herhangi bir slot-signal mekanizması kullanmadığınız için, bu ifade de kısa sürede programın donmasına yol açacaktır.

slot-signal mekanizması kullanılsa bile python3 -c "input('>>> ')" ifadesi donmaya sebep olur çünkü yukarıda bahsettiğim gibi input, Python ortamına aittir ve terminal için oluşturulan sürecin alt sürecinde çalışır.

Eğer bir şekilde python ortamına girmeyi başarsanız bile, yazacağınız komutlar, subprocess.run kullandığınız için, yeni bir süreç olarak çalışmaya başlayacak.

slot-signal konusunda hem fikirim fakat diğer dediklerinizi kavrayamadım.

import sys
import getpass

users = {
    "admin": "password123",
    "user1": "mypassword",
}

def login():

    username = input("Kullanıcı Adı: ")
    password = getpass.getpass("Şifre: ")

    if username in users and users[username] == password:
        print("Giriş başarılı!")
    else:
        print("Kullanıcı adı veya şifre hatalı.")

if __name__ == "__main__":
    login()

aşağıdaki kodu benim ilk attığım koddaki console dan çağırmayı dener misiniz ?

Aşağıdaki kodlar vasıtasıyla terminal ortamından python ortamına, python ortamından da geri terminal ortamına geçiş yapabiliriz. Ama input’u yani sys.stdin’i yönetmek için başka bir mekanizmaya ihtiyacınız var.

import sys
import subprocess
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit
from PyQt5.QtGui import QTextCursor
from PyQt5.QtCore import Qt, QThread, pyqtSignal


class StdIO:
    """
    Std çıktıları QTextEdit'e yönlendirmek için pseudo bir sınıf.
    """
    def __init__(self, widget):
        self.widget = widget

    def write(self, text):
        """
        QTextEdit için pseduo write metodu
        """
        cursor = self.widget.textCursor()
        cursor.movePosition(QTextCursor.End)
        cursor.insertText(text)
        self.widget.setTextCursor(cursor)
        self.widget.ensureCursorVisible()

    def flush(self):
        pass

    def readline(self):
        """
        QTextEdit için pseduo satır okuma metodu
        """
        cursor = self.widget.textCursor()
        cursor.movePosition(QTextCursor.StartOfBlock)
        cursor.select(QTextCursor.BlockUnderCursor)
        command = cursor.selectedText().strip()
        return command


class Worker(QThread):
    finished = pyqtSignal(str)

    def __init__(self, command, parent=None):
        super().__init__(parent)
        self.command = command

    def run(self):
        try:
            process = subprocess.Popen(
                self.command,
                shell=True,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                text=True
            )
            stdout, stderr = process.communicate()
            output = stdout + stderr
        except Exception as e:
            output = str(e)
        self.finished.emit(output)


class CommandLineWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.worker = None
        self.console = QTextEdit(self)
        self.io = StdIO(self.console)
        self.python_console = False
        self.config()

    def config(self):
        self.console.setReadOnly(True)
        self.console.setStyleSheet("background-color: black; color: white;")
        self.setCentralWidget(self.console)
        self.console.setTextInteractionFlags(Qt.TextEditorInteraction)
        self.console.setPlaceholderText('Enter commands and press Enter...')
        self.console.installEventFilter(self)
        self.setWindowTitle('Terminal Interface')
        self.setGeometry(100, 100, 800, 600)

    def eventFilter(self, obj, event):
        if obj is self.console and event.type() == event.KeyPress:
            key = event.key()
            if key in (Qt.Key_Enter, Qt.Key_Return):
                self.process_command()
                return True
        return super().eventFilter(obj, event)

    def process_command(self):
        cursor = self.console.textCursor()
        cursor.movePosition(QTextCursor.StartOfBlock)
        cursor.select(QTextCursor.BlockUnderCursor)
        command = cursor.selectedText().strip()
        cursor.removeSelectedText()
        self.console.append(f'{command}\n')
        if command == "python3":
            self.python_console = True
            self.console.append("Entering Python interactive mode.\nType 'exit()' to return.\n")
            sys.stdin = self.io
            sys.stdout = self.io
            sys.stderr = self.io
            return
        if self.python_console:
            if command.strip() == "exit()":
                self.python_console = False
                sys.stdin = sys.__stdin__
                sys.stdout = sys.__stdout__
                sys.stderr = sys.__stderr__
                self.console.append("Exited Python interactive mode.\n")
            else:
                try:
                    exec(command)
                except Exception as e:
                    self.io.write(f"Error: {e}\n")
        else:
            self.worker = Worker(command)
            self.worker.finished.connect(self.process_finished)
            self.worker.start()

    def process_finished(self, output):
        self.console.append(output)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    terminal = CommandLineWindow()
    terminal.show()
    sys.exit(app.exec_())

Sorun sadece python ortamına girmekle alakalı değil, ki yukarıdaki kodlar, alt bir process olarak açılan python’ın kodlarını işletmez. pseudo bir python ortamı sunar ve biz python3 yazarak sanki python ortamını aktif ediyormuşuz gibi bir hisse kapılırız. Ama böyle bir durum söz konusu değil. Daha doğrusu böyle bir süreci başlatan bir mekanizma tanımlı değil.

terminal’den python’a geçtiğimizde, QTextEdit widgetine yazılan her yazı subprocess.run veya subprocess.Popen şeklinde yeni bir process olarak oluşturulmuyor. Aksine yazılan yazılar exec fonksiyonu ile değerlendiriliyor.

Şayet exit() yazarsanız, bu sefer std çıktılar değiştiriliyor. Ve terminal konsolundaki komutları işletmeye devam edebiliyorsunuz.

Ancak temelde yukarıdaki kodlar bize sanal olarak bir python konsolu arayüzü sunuyor. Ama aslında terminaldeki bir alt süreç olarak python ortamı açmıyoruz.

Mesela node yazıp enter tuşuna bastığımızda, program nodejs’nin ortamını açar. Ancak bir sonraki satırda yazacaklarımız, yeni bir subprocess için geçerli olacağı için, herhangi bir kodu node konsolunda çalıştıramayız.

nasıl yapacağız peki hocam aklınızda bir şey geliyor mu ?

Her bir alt süreç için geçerli olacak jenerik bir worker sınıfı tanımlayıp, gelen komutlara göre hangi worker’ın oluşturulacağını veya komutun tipine göre yeni worker oluşturmanın gerekip gerekmediğini denetleyebiliriz.

Yani python3 yazıp enter tuşuna bastığımızda, program python konsolundan çıkana kadar yeni bir worker ve process oluşturmamalı. Öyle değil mi?

Aynı durum nodejs için de geçerli. Eğer yeni bir alt süreç açtıysak, bu alt süreç sonlanana kadar yeni bir süreç açmamak, zaten açılmış olan süreçten devam etmek gerekiyor.

Alt süreçleri yönetmek için SubProcess isimli yeni bir worker sınıf tanımlıyorum. Bu sınıfı, hem python; hem nodejs hem de başka programlar için kullanabiliriz.

import sys
import subprocess
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit
from PyQt5.QtGui import QTextCursor
from PyQt5.QtCore import Qt, QThread, pyqtSignal


class TerminalWorker(QThread):
    finished = pyqtSignal(str)

    def __init__(self, command, parent=None):
        super().__init__(parent)
        self.command = command

    def run(self):
        try:
            process = subprocess.Popen(
                self.command,
                shell=True,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                text=True
            )
            stdout, stderr = process.communicate()
            output = stdout + stderr
        except Exception as e:
            output = str(e)
        self.finished.emit(output)


class SubWorker(QThread):
    finished = pyqtSignal(str)

    def __init__(self, process, parent=None):
        super().__init__(parent)
        self.process = process

    def run(self):
        while True:
            output = self.process.stdout.readline()
            if output:
                self.finished.emit(output.replace(">>> ", ""))
            else:
                break


class CommandLineWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.console = QTextEdit(self)
        self.terminal_process = None
        self.terminal_worker = None
        self.python_process = None
        self.python_worker = None
        self.node_process = None
        self.node_worker = None
        self.config()

    def config(self):
        self.console.setReadOnly(False)
        self.console.setStyleSheet("background-color: black; color: white;")
        self.setCentralWidget(self.console)
        self.console.setTextInteractionFlags(Qt.TextEditorInteraction)
        self.console.setPlaceholderText('Enter commands and press Enter...')
        self.console.installEventFilter(self)
        self.setWindowTitle('Terminal Interface')
        self.setGeometry(100, 100, 800, 600)

    def eventFilter(self, obj, event):
        if obj is self.console and event.type() == event.KeyPress:
            key = event.key()
            if key in (Qt.Key_Enter, Qt.Key_Return):
                self.process_command()
                return True
        return super().eventFilter(obj, event)

    def process_command(self):
        cursor = self.console.textCursor()
        cursor.movePosition(QTextCursor.StartOfBlock)
        cursor.select(QTextCursor.BlockUnderCursor)
        command = cursor.selectedText().strip()
        cursor.removeSelectedText()
        self.console.append(f'{command}\n')
        if command == "python3" and not self.python_process:
            self.start_python_process()
        elif command == "node" and not self.node_process:
            self.start_node_process()
        elif self.node_process:
            self.execute_node_command(command)
        elif self.python_process:
            self.execute_python_command(command)
        else:
            self.execute_terminal_command(command)

    def start_python_process(self):
        self.python_process = subprocess.Popen(
            ["python3", "-i"],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1
        )
        self.python_worker = SubWorker(self.python_process)
        self.python_worker.finished.connect(self.subprocess_finished)
        self.python_worker.start()

    def start_node_process(self):
        self.node_process = subprocess.Popen(
            ["node", "-i"],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1
        )
        self.node_worker = SubWorker(self.node_process)
        self.node_worker.finished.connect(self.subprocess_finished)
        self.node_worker.start()

    def execute_node_command(self, command):
        if self.node_process:
            self.node_process.stdin.write(f'{command}\n')
            self.node_process.stdin.flush()
            if command == "exit":
                self.node_process = False

    def execute_python_command(self, command):
        if self.python_process:
            self.python_process.stdin.write(f'{command}\n')
            self.python_process.stdin.flush()
            if command == "exit()":
                self.python_process = False

    def execute_terminal_command(self, command):
        self.terminal_worker = TerminalWorker(command)
        self.terminal_worker.finished.connect(self.terminal_process_finished)
        self.terminal_worker.start()

    def subprocess_finished(self, output):
        self.console.append(output)

    def terminal_process_finished(self, data):
        self.console.append(data)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    terminal = CommandLineWindow()
    terminal.show()
    sys.exit(app.exec_())

Burada artık pseudo bir sınıf kullanmadık. Açtığımız prosesleri yönetmeye çalıştık.

Örneğin, yukarıda, üç adet worker tanımlandığını görüyorsunuz.

İlk worker, terminal kodlarını çalıştırmak için,
İkinci worker, python kodlarını çalıştırmak için,
Üçüncü worker da node kodlarını çalıştırmak için oluşturulmuş workerlar.

İkinci worker, command, python3 olduğunda, üçüncü worker ise command node olduğunda çalışıyor.

    def process_command(self):
        cursor = self.console.textCursor()
        cursor.movePosition(QTextCursor.StartOfBlock)
        cursor.select(QTextCursor.BlockUnderCursor)
        command = cursor.selectedText().strip()
        cursor.removeSelectedText()
        self.console.append(f'{command}\n')
        if command == "python3" and not self.python_process:
            self.start_python_process()
        elif command == "node" and not self.node_process:
            self.start_node_process()
        elif self.node_process:
            self.execute_node_command(command)
        elif self.python_process:
            self.execute_python_command(command)
        else:
            self.execute_terminal_command(command)

Yukarıdaki koşul ifadelerini inceleyelim:

İlk koşul ifadesi, eğer command’ın değeri "python3" ise ve bir python süreci açılmamışsa, anlamına geliyor. Bu durumda aşağıdaki fonksiyon çağrılır:

    def start_python_process(self):
        self.python_process = subprocess.Popen(
            ["python3", "-i"],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1
        )
        self.python_worker = SubWorker(self.python_process)
        self.python_worker.finished.connect(self.subprocess_finished)
        self.python_worker.start()

İkinci koşul ifadesi ise, eğer command’ın değeri "node" ise ve bir node süreci açılmamışsa, anlamına geliyor. Bu durumda da aşağıdaki fonksiyon çağrılır:

    def start_node_process(self):
        self.node_process = subprocess.Popen(
            ["node", "-i"],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1
        )
        self.node_worker = SubWorker(self.node_process)
        self.node_worker.finished.connect(self.subprocess_finished)
        self.node_worker.start()

elif self.node_process: ifadesi, node süreci açıldığında çalışır ve execute_node_command fonksiyonu çağrılır:

    def execute_node_command(self, command):
        if self.node_process:
            self.node_process.stdin.write(f'{command}\n')
            self.node_process.stdin.flush()
            if command == "exit":
                self.node_process = False

elif self.python_process: ifadesi ise, python3 süreci açıldığında çalışır ve execute_python_command fonksiyonu çağrılır:

    def execute_python_command(self, command):
        if self.python_process:
            self.python_process.stdin.write(f'{command}\n')
            self.python_process.stdin.flush()
            if command == "exit()":
                self.python_process = False

Her iki execute fonksiyonunda da yeni prosesler açılmadığını, mevcut proseslere komutların işlendiğini görüyorsunuz.

Bu arada artık python konsolunu aktif ettikten sonra, input fonksiyonunu kullanabilirsiniz.

Ancak hala terminal davranışının alıştığınız python konsoluna benzemesi için azı manipülasyonlar yapmanız gerekir.

Öte yandan, geri kalan diğer terminal işlemleri, şimdilik aşağıdaki fonksiyon yardımıyla çalıştırılır:

    def execute_terminal_command(self, command):
        self.terminal_worker = TerminalWorker(command)
        self.terminal_worker.finished.connect(self.terminal_process_finished)
        self.terminal_worker.start()

execute_terminal_command fonksiyonundaki her bir terminal çağrısı, birbirinden bağımsız süreçler olarak yaratılır.

can only concatenate str (not "NoneType") to str

Ne yaptıktan sonra böyle bir çıktı aldığınızı açıklamamışsınız.

attığınız kodu, python3 login.py , python3 , command python3 v.b tüm varyasyonlarla denedim fakat bu hata var. İpconfig, tree, wmic bios getserialnumber gibi standart console komutlarındada aynı.

Bir daha deneyin:

import sys
import subprocess
from PyQt5.QtWidgets import QApplication, QMainWindow, QTextEdit
from PyQt5.QtGui import QTextCursor
from PyQt5.QtCore import Qt, QThread, pyqtSignal


class TerminalWorker(QThread):
    finished = pyqtSignal(str)

    def __init__(self, command, parent=None):
        super().__init__(parent)
        self.command = command

    def run(self):
        try:
            process = subprocess.Popen(
                self.command,
                shell=True,
                stdin=subprocess.PIPE,
                stdout=subprocess.PIPE,
                stderr=subprocess.STDOUT,
                text=True
            )
            stdout, _ = process.communicate()
            output = stdout
        except Exception as e:
            output = str(e)
        self.finished.emit(output)


class SubWorker(QThread):
    finished = pyqtSignal(str)

    def __init__(self, process, parent=None):
        super().__init__(parent)
        self.process = process

    def run(self):
        while True:
            output = self.process.stdout.readline()
            if output:
                self.finished.emit(output.replace(">>> ", ""))
            else:
                break


class CommandLineWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.console = QTextEdit(self)
        self.terminal_process = None
        self.terminal_worker = None
        self.python_process = None
        self.python_worker = None
        self.node_process = None
        self.node_worker = None
        self.config()

    def config(self):
        self.console.setReadOnly(False)
        self.console.setStyleSheet("background-color: black; color: white;")
        self.setCentralWidget(self.console)
        self.console.setTextInteractionFlags(Qt.TextEditorInteraction)
        self.console.setPlaceholderText('Enter commands and press Enter...')
        self.console.installEventFilter(self)
        self.setWindowTitle('Terminal Interface')
        self.setGeometry(100, 100, 800, 600)

    def eventFilter(self, obj, event):
        if obj is self.console and event.type() == event.KeyPress:
            key = event.key()
            if key in (Qt.Key_Enter, Qt.Key_Return):
                self.process_command()
                return True
        return super().eventFilter(obj, event)

    def process_command(self):
        cursor = self.console.textCursor()
        cursor.movePosition(QTextCursor.StartOfBlock)
        cursor.select(QTextCursor.BlockUnderCursor)
        command = cursor.selectedText().strip()
        cursor.removeSelectedText()
        self.console.append(f'{command}\n')
        if command == "python3" and not self.python_process:
            self.start_python_process()
        elif command == "node" and not self.node_process:
            self.start_node_process()
        elif self.node_process:
            self.execute_node_command(command)
        elif self.python_process:
            self.execute_python_command(command)
        else:
            self.execute_terminal_command(command)

    def start_python_process(self):
        self.python_process = subprocess.Popen(
            ["python3", "-i"],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1
        )
        self.python_worker = SubWorker(self.python_process)
        self.python_worker.finished.connect(self.subprocess_finished)
        self.python_worker.start()

    def start_node_process(self):
        self.node_process = subprocess.Popen(
            ["node", "-i"],
            stdin=subprocess.PIPE,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
            text=True,
            bufsize=1
        )
        self.node_worker = SubWorker(self.node_process)
        self.node_worker.finished.connect(self.subprocess_finished)
        self.node_worker.start()

    def execute_node_command(self, command):
        if self.node_process:
            self.node_process.stdin.write(f'{command}\n')
            self.node_process.stdin.flush()
            if command == "exit":
                self.node_process = None

    def execute_python_command(self, command):
        if self.python_process:
            self.python_process.stdin.write(f'{command}\n')
            self.python_process.stdin.flush()
            if command == "exit()":
                self.python_process = None

    def execute_terminal_command(self, command):
        self.terminal_worker = TerminalWorker(command)
        self.terminal_worker.finished.connect(self.terminal_process_finished)
        self.terminal_worker.start()

    def subprocess_finished(self, output):
        self.console.append(output)

    def terminal_process_finished(self, data):
        self.console.append(data)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    terminal = CommandLineWindow()
    terminal.show()
    sys.exit(app.exec_())
python login.py

Kullanıcı Adı: Traceback (most recent call last):
  File "C:\Users\PC\Desktop\New folder (2)\login.py", line 23, in <module>
    login()
  File "C:\Users\PC\Desktop\New folder (2)\login.py", line 14, in login
    username = input("Kullan\u0131c\u0131 Ad\u0131: ")
EOFError: EOF when reading a line

login.py

import sys
import getpass

users = {
    "admin": "password123",
    "user1": "mypassword",
}

def login():

    username = input("Kullanıcı Adı: ")
    password = getpass.getpass("Şifre: ")

    if username in users and users[username] == password:
        print("Giriş başarılı!")
    else:
        print("Kullanıcı adı veya şifre hatalı.")

if __name__ == "__main__":
    login()

Olabilir. input’u çalıştırıyor normalde.

Programın tam bir konsol uygulamasına dönüşebilmesi için daha çok uğraşmak lazım.