Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Setting size of terminal spawned by QProcess



  • I am writing a widget that displays a terminal emulator within my programm

    class EmbeddedTerminal(QWidget):
        finished = pyqtSignal()
    
        def __init__(self, parent=None):
            super(EmbeddedTerminal, self).__init__(parent)
            self.process = QProcess(self)
            self.process.finished.connect(self.term_finished)
            self.terminal = QWidget(self)
            layout = QVBoxLayout(self)
            layout.addWidget(self.terminal)
            self.process.start('alacritty', ['--embed', str(int(self.winId()))])
    
        @pyqtSlot()
        def term_finished(self):
            self.finished.emit()
    

    When I start this widget, the terminal is always 640x480 pixels, but I want it do take as much space as possible. As far as I can tell there should be two ways
    First, the Layout should tell the Process to take the space (preferred way, but I don't know how).
    Second, I need the width and height in pixels of the available space, to calculate the dimensions of the terminal by hand and give it as a parameter in process.start().

    I really don't want to have to resort to the second option. Any suggestions on how to solve the issue? Maybe something completely different I did not think of?

    Thanks in advance!


  • Qt Champions 2019

    @julkip said in Setting size of terminal spawned by QProcess:

    self.process.start('alacritty', ['--embed', str(int(self.winId()))])

    You are providing the winId from your EmbeddedTerminal widget, not self.terminal inside EmbeddedTerminal.



  • Changing self.winID() to self.terminal.winID() does not change the behaviour of the terminal unfortunately.


  • Banned

    Okay first it would have been extremely helpful for you to get a quicker answer had you supplied a MRE (Minimal Reproducible Example) instead of a code snippet as you have because now if we want to do you the favor you are requesting we have to make the MUC (Minimal Usable Code) that uses your code snippet and we might not be using it the same way you are.


  • Banned

    Okay I went and grabbed where you might have pulled your snippet from and implemented that within this MUC -- now interestingly enough if I substitute ConEmu in place of your alacritty I get an error that ConEmu does not support the embed command -- which means maybe it is not doing what you think its doing when you make your call of course I am not 100% sure about that. Now calling cmd.exe works in that the window comes up but nothing is displayed. Still perhaps this might help you some in figuring out a bit more about what it is doing and what it is not. From my research into this the general consensus was that you cannot embed a terminal/console into widget but I am not confident on those answers either so there still maybe a way to do this but it will take a lot more research or finding someone else who has implemented something like this. Can I ask why you are wanting to embed a terminal in your PyQt GUI rather than not just emulating one using QTextEdit ?? That seems a lot simpler to me than trying to embed another program into your program basically trying to make your program a shell of a sorts.

    from PyQt5.QtCore    import QProcess, pyqtSignal, pyqtSlot
    #from PyQt5.QtGui     import 
    from PyQt5.QtWidgets import QApplication, QMainWindow, QWidget, QTabWidget
    from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QTextEdit
    
    class EmbeddedTerminal(QWidget):
        finished = pyqtSignal()
    
        def __init__(self, parent=None):
          # super(EmbeddedTerminal, self).__init__(parent)
          # First you should not use super( ) in Python as it introduces 4 known issues 
          # that must be handled properly. Further there were still actual bugs within
          # the usage of super( ) when used in Python. Yes while super( ) works fine 
          # within C++ it does not work as seamlessly within Python due to the major 
          # differences between these 2 languages. Next the reason it was created was 
          # to handle a rather rare issue and unless you are doing some complicated 
          # inheritance you will most likely never run into this extremely rare issue
          # However the 4 major issues that get included by using super( ) you are much 
          # more likely to occur than that rare issue its meant for to solve. Of course
          # using the basic explicit method, as follows, does not cause these issues and 
          # is as just as simple as using `super( )` further you do not actually gain 
          # anything useful by using `super( )` in Python that could not be done in a 
          # much safer manner.
            QWidget.__init__(self)
    
            self.process = QProcess(self)
            self.process.finished.connect(self.TermExited)
            self.process.setWorkingDirectory("C:/DJ_Office/Students")
    
          # This was not doing anything at all
    #        self.Term = QWidget(self)
    #        VBox = QVBoxLayout(self)
    #        VBox.addWidget(self.Term)
    
    #        self.process.start('C:/Program Files/ConEmu/ConEmu64.exe' ['-embed', str(int(self.winId()))])
            self.process.start('C:/Windows/SysWOW64/cmd.exe', ['-embed', str(int(self.winId()))])
    #        self.process.waitForStarted()
    #        self.process.start('alacritty', ['-embed', str(int(self.winId()))])
    
          # I even tried doing this and it does nothing
    #        self.terminal = QWidget(self)
    
    #        VBox = QVBoxLayout(self)
    #        VBox.addWidget(self.terminal)
    
          # I even tried doing this and it fails because you it does not handle adding the process
    #        VBox = QVBoxLayout(self)
    #        VBox.addWidget(self.process)
            
    #        self.setLayout(VBox)
    
        @pyqtSlot()
        def TermExited(self):
            print('******* Have Exited Terminal')
    #        self.finished.emit()
    
    class PlainView(QWidget):
        def __init__(self):
            QWidget.__init__(self)
            
            self.txeDisplay = QTextEdit()
            
            HBox = QHBoxLayout()
            HBox.addWidget(self.txeDisplay)
            
            self.setLayout(HBox)
            
    
    class CenterPanel(QWidget):
        def __init__(self):
            QWidget.__init__(self)
    
            self.PlainTab = PlainView()
            
            self.EmbdTerm = EmbeddedTerminal()
    
            self.tbwTabs = QTabWidget()
            self.tbwTabs.addTab(self.EmbdTerm, "EmbdedTerm")
            self.tbwTabs.addTab(self.PlainTab, "TextEditer")
    
            VBox = QVBoxLayout()
            VBox.addWidget(self.tbwTabs)
            
            self.setLayout(VBox)
    
    class MainWindow(QMainWindow):
        def __init__(self):
            QMainWindow.__init__(self)
    
            self.CenterPane = CenterPanel()
            self.setCentralWidget(self.CenterPane)
    
    if __name__ == "__main__":
        MainEvntThred = QApplication([])
    
        MainApplication = MainWindow()
        MainApplication.show()
    
        MainEvntThred.exec()
    

Log in to reply