pya gui with QT - Edited

edited January 2021 in Python scripting

More Edits trying too add QDialogButtonBox and trying to display it
Any help would be appreciated

#ButtonBox
self.first = QLineEdit(self)
self.second = QLineEdit(self)
buttonBox = QDialogButtonBox.new(self);

layout = QFormLayout(self)
layout.addRow("First text", self.first)
layout.addRow("Second text", self.second)
layout.addWidget(buttonBox)
self.setLayout(layout)
self.setWindowTitle("Form Layout - KLayout")

def getInputs(self):
    return (self.first.text(), self.second.text())      

So Deleted Previous Post after Banging the mouse all day here is the Code For pya GUI
with several examples, much simpler and cleaner

 import pya

 class GuiDialog(pya.QDialog):
  """
   This class implements a  Gui Dialog With Several Examples

  """

  view = pya.Application.instance().main_window().current_view()

  def __init__(self, parent = None):
    """ Dialog constructor """
   super(GuiDialog, self).__init__()

  # text input    
  text=  QInputDialog.getText(self, 'getText', 'Enter text', QLineEdit.Normal, "")                                                                                                                   
  print(text)       

  # multi-line input                                                                                                                       
  text = QInputDialog.getMultiLineText(self, 'getMultiLineText', 'Story', "Enter story")                                         
  print(text)     

  # enter double                                                                                                                 
  double = QInputDialog.getDouble(self, 'getDouble', 'Enter double', 22.33, -10000, 10000, 2)                                    
  print(double)                                                                                                                  

  # enter integer                                                                                                                                   
  int= QInputDialog.getInt(self, 'getInteger', 'Enter number', 25, 0, 100, 1)                                                   
  print(int)                                                                                                                     

  # select option                                                                                                                                   
  items = ["Spring", "Summer", "Fall", "Winter"]  
  item = QInputDialog.getItem(self, 'getItem', 'Favourite season', items, 0, False)                                                                                    
  print(item)                         

  # Instantiate the dialog and make it visible initially.
  # Passing the main_window will make it stay on top of the main window.
  dialog = GuiDialog(pya.Application.instance().main_window())

Comments

  • @tagger5896 Thanks too for sharing this ... although I sense some frustration and I can't see your original post. I hope the issues have not been too severe.

    Matthias

  • edited January 2021

    Matthias
    The scope is too document all the gui inputs ,
    documentation is sparse, and I think it will help.
    I am stuck with the following from a previous post
    I see how it get's the click but can't get the inputs from the text inputs too print out
    or cancel or end the button click.
    Yes it's frustrating , I can copy paste all online QDialog examples into Spyder and works as supplied
    not so much with Klayout

    def test(buttonName):
        print("Clicked: " + buttonName)
    
    
       dialog = pya.QDialog.new(pya.Application.instance().main_window())
       dialog.layout = pya.QFormLayout(dialog)
      #text=  QInputDialog.getText(dialog, 'getText', 'Enter text', QLineEdit.Normal, "")         
    
      xL = QLabel('X Start',dialog)
     first = QLineEdit(dialog)
     yL = QLabel('Y Start',dialog)
     second = QLineEdit(dialog)
    
     dialog.layout.addWidget(xL)
     dialog.layout.addWidget(first)
    
    dialog.layout.addWidget(yL)
    dialog.layout.addWidget(second)
    
    b1 = pya.QPushButton("Ok", dialog)
    dialog.layout.addWidget(b1)
    b1.clicked = lambda: test("B1")
    
    b2 = pya.QPushButton("Cancel", dialog)
    dialog.layout.addWidget(b2)
    b2.clicked = lambda: test("B2")
    
    #################
    dialog.show()
    #################
    
  • Hi @tagger5896 ,

    Maybe I can help you with your struggle. Could you quickly explain what you are trying to accomplish with the click?

    I am not exactly sure what you are trying to accomplish, but the text is in first.text or second.text from your example. So if you just print out those it works.

    I have a somewhat more complex Qt-Dialog in my repo https://github.com/sebastian-goeldi/kgit/blob/master/python/kgit/menu.py , though I never finished it because it is too slow and unresponsive (at least for my taste). Let me know if you would like some explanations or how to do certain things in Qt as I have had my fair share of struggles with Qt-Dialogs in KLayout (though I have to say kudos to @Matthias for even exposing the API to make Qt interactions possible).

  • Thanks for your input Sebastian,
    This works well in Spyder with python 3.7
    not so much in Klayout

    # importing libraries 
    import pya
    import sys 
    
    # creating a class 
    # that inherits the QDialog class 
    class Window(pya.QDialog): 
    
    # Dialog constructor 
    def __init__(self, parent = None): 
        super(Window, self).__init__() 
    
        # setting window title 
        self.setWindowTitle("Klayout A* Star") 
    
        # setting geometry to the window 
        self.setGeometry(100, 100, 100, 100) 
    
        # creating a group box 
        self.formGroupBox = QGroupBox("A* Star") 
    
        # creating a line edit 
        self.nameLineEdit1 = QLineEdit() 
        self.nameLineEdit2 = QLineEdit()    
        self.nameLineEdit3 = QLineEdit() 
        self.nameLineEdit4 = QLineEdit() 
    
    # calling the method that creates the form 
        self.createForm() 
    
        # creating a dialog button for ok and cancel 
        self.buttonBox = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel) 
    
        # adding action when form is accepted 
        self.buttonBox.accepted.connect(self.getInfo) 
    
        # addding action when form is rejected 
        self.buttonBox.rejected.connect(self.reject) 
    
        # creating a vertical layout 
        mainLayout = QVBoxLayout() 
    
        # adding form group box to the layout 
        mainLayout.addWidget(self.formGroupBox) 
    
        # adding button box to the layout 
        mainLayout.addWidget(self.buttonBox) 
    
        # setting lay out 
        self.setLayout(mainLayout) 
    
    # get info method called when form is accepted 
    def getInfo(self): 
    
        # printing the form information 
        print("Xstart : {0}".format(self.nameLineEdit1.text())) 
        print("Ystart : {0}".format(self.nameLineEdit2.text()))         
        print("Xend : {0}".format(self.nameLineEdit3.text())) 
        print("Yend : {0}".format(self.nameLineEdit4.text())) 
        # closing the window 
        self.close() 
    
    # create form method 
    def createForm(self): 
    
        # creating a form layout 
        layout = QFormLayout() 
    
        # adding rows 
        # for name and adding input text 
        layout.addRow(QLabel("Xstart"), self.nameLineEdit1) 
        layout.addRow(QLabel("Ystart"), self.nameLineEdit2)        
        layout.addRow(QLabel("Xend"), self.nameLineEdit3) 
        layout.addRow(QLabel("Yend"), self.nameLineEdit4)  
    
        # setting layout 
        self.formGroupBox.setLayout(layout) 
    
    
    GUI_Klayout = Window(pya.Application.instance().main_window())
    GUI_Klayout.show()
    
  • Hi @tagger5896 ,

    As I mentioned before, KLayout doesn't use the exact same stuff as pyqt. It is more close to the C++ Qt. Therefore you have to change some stuff in your code. You can get a running example as follows. The GroupBox is quite different and the text of the lineedits can be called directly by .text, i.e. it's an attribute not a function. Full working code below.

    # importing libraries 
    from pya import *
    import sys 
    
    # creating a class 
    # that inherits the QDialog class 
    class Dialog(pya.QDialog): 
    
      # Dialog constructor 
      def __init__(self, parent = None): 
          pya.QDialog.__init__(self)
    
          # setting window title 
          self.setWindowTitle("Klayout A* Star") 
    
          # setting geometry to the window 
          self.setGeometry(100, 100, 100, 100) 
    
          # creating a group box 
          self.formGroupBox = QGroupBox("A* Star") 
          vb = pya.QVBoxLayout(self.formGroupBox)
    
    
          # creating a line edit 
          self.nameLineEdit1 = QLineEdit(self.formGroupBox)
          vb.addWidget(self.nameLineEdit1)
          self.nameLineEdit2 = QLineEdit(self.formGroupBox)    
          vb.addWidget(self.nameLineEdit2)
          self.nameLineEdit3 = QLineEdit(self.formGroupBox) 
          vb.addWidget(self.nameLineEdit3)
          self.nameLineEdit4 = QLineEdit(self.formGroupBox)
          vb.addWidget(self.nameLineEdit4)
    
          # creating a dialog button for ok and cancel 
          self.buttonBox = QDialogButtonBox(self)#.new_buttons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
          #self.buttonBox.buttonRole(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
          self.ok = self.buttonBox.addButton(QDialogButtonBox.Ok)
          self.cancel = self.buttonBox.addButton(QDialogButtonBox.Cancel)
    
          #(self.buttonBox.)
    
          # adding action when form is accepted 
          self.cancel.clicked(lambda button: self.reject())
    
          # addding action when form is rejected 
          self.ok.clicked(self.getInfo)
    
          # creating a vertical layout 
          mainLayout = QVBoxLayout() 
    
          # adding form group box to the layout 
          mainLayout.addWidget(self.formGroupBox) 
    
          # adding button box to the layout 
          mainLayout.addWidget(self.buttonBox) 
    
          # setting lay out 
          self.setLayout(mainLayout) 
    
      # get info method called when form is accepted 
      def getInfo(self): 
    
          # printing the form information 
          print("Xstart : {0}".format(self.nameLineEdit1.text)) 
          print("Ystart : {0}".format(self.nameLineEdit2.text))         
          print("Xend : {0}".format(self.nameLineEdit3.text)) 
          print("Yend : {0}".format(self.nameLineEdit4.text)) 
          # closing the window 
          self.close()
    
      # create form method 
      def createForm(self): 
    
          # creating a form layout 
          layout = QFormLayout() 
    
          # adding rows 
          # for name and adding input text 
          layout.addRow(QLabel("Xstart"), self.nameLineEdit1) 
          layout.addRow(QLabel("Ystart"), self.nameLineEdit2)        
          layout.addRow(QLabel("Xend"), self.nameLineEdit3) 
          layout.addRow(QLabel("Yend"), self.nameLineEdit4)  
    
          # setting layout 
          self.formGroupBox.setLayout(layout)
    
    
    GUI_Klayout = Dialog(pya.Application.instance().main_window())
    GUI_Klayout.exec_()
    
  • sebastian,
    tyvm for clairfying this I am still new too Python and Ruby flavors of Klayout we all are at some point
    Tracy

  • Update thanks to Sebastian for multi-line input, slowly getting there , it's progress

    # Enter your Python code here
    # importing libraries 
    from pya import *
    import sys 
    import tkinter as tk
    from tkinter import filedialog
    from tkinter.colorchooser import askcolor
    from tkinter import ttk
    import tkinter.scrolledtext as tkst
    import tkinter.font
    
    
    class GuiDialog(pya.QDialog):
      """
      This class implements a  Gui Dialog With Several Examples
    
      """
      print(sys.version)
      view = pya.Application.instance().main_window().current_view()
    
      def __init__(self, parent = None):
        """ Dialog constructor """
        super(GuiDialog, self).__init__()
    
       # text input    
        text=  QInputDialog.getText(self, 'getText', 'Enter text', QLineEdit.Normal, "")                                                                                                                   
        print(text)       
    
        # multi-line input                                                                                                                       
        text = QInputDialog.getMultiLineText(self, 'getMultiLineText', 'Story', "Enter story")                                         
        print(text)     
    
        # enter double                                                                                                                 
        double = QInputDialog.getDouble(self, 'getDouble', 'Enter double', 22.33, -10000, 10000, 2)                                    
        print(double)                                                                                                                  
    
        # enter integer                                                                                                                                   
        int= QInputDialog.getInt(self, 'getInteger', 'Enter number', 25, 0, 100, 1)                                                   
        print(int)                                                                                                                     
    
        # select option                                                                                                                                   
        items = ["Spring", "Summer", "Fall", "Winter"]  
        item = QInputDialog.getItem(self, 'getItem', 'Favourite season', items, 0, False)                                                                                    
        print(item)      
    
       #File Dialogs
        #Singal File
        fileName = QFileDialog.getOpenFileName(self,"QFileDialog.getOpenFileName()", "","All Files (*);;Python Files (*.py)")
        if fileName:
            print(fileName)
       # print file contents
        with open(fileName, 'r') as f:
            print(f.read())
    
       #mutipile Files
        files  = QFileDialog.getOpenFileNames(self,"QFileDialog.getOpenFileNames()", "","All Files (*);;Python Files (*.py)")
        if files:
                print(files)
    
        #Save File
        fileName = QFileDialog.getSaveFileName(self,"QFileDialog.getSaveFileName()","","All Files (*);;Text Files (*.txt)")
        if fileName:
                print(fileName)
    
    
    # Instantiate the dialog and make it visible initially.
    # Passing the main_window will make it stay on top of the main window.
    dialog = GuiDialog(pya.Application.instance().main_window())         
    
        #Sebastian's, code to add multi-line input
    # creating a class 
    # that inherits the QDialog class 
    class Dialog(pya.QDialog): 
    
      # Dialog constructor 
      def __init__(self, parent = None): 
          pya.QDialog.__init__(self)
    
          # setting window title 
          self.setWindowTitle("Klayout A* Star") 
    
          # setting geometry to the window 
          self.setGeometry(100, 100, 100, 100) 
    
          # creating a group box 
          self.formGroupBox = QGroupBox() 
          vb = pya.QVBoxLayout(self.formGroupBox)
          hb = pya.QHBoxLayout(self.formGroupBox)      
    
          #Create Labels
          self.x1 = QLabel('Xstart')
          self.y1 = QLabel('Ystart')     
          self.x2 = QLabel('Xend')
          self.y2 = QLabel('Yend')       
    
          # creating a line edit 
          self.nameLineEdit1 = QLineEdit(self.formGroupBox)
          vb.addWidget(self.x1)
          vb.addWidget(self.nameLineEdit1)
    
          self.nameLineEdit2 = QLineEdit(self.formGroupBox) 
          vb.addWidget(self.y1)   
          vb.addWidget(self.nameLineEdit2)
    
          self.nameLineEdit3 = QLineEdit(self.formGroupBox)
          vb.addWidget(self.x2) 
          vb.addWidget(self.nameLineEdit3)
    
          self.nameLineEdit4 = QLineEdit(self.formGroupBox)
          vb.addWidget(self.y2)
          vb.addWidget(self.nameLineEdit4)
    
          # creating a dialog button for ok and cancel 
          self.buttonBox = QDialogButtonBox(self)#.new_buttons(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
          #self.buttonBox.buttonRole(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
          self.ok = self.buttonBox.addButton(QDialogButtonBox.Ok)
          self.cancel = self.buttonBox.addButton(QDialogButtonBox.Cancel)
    
          #(self.buttonBox.)
    
          # adding action when form is accepted 
          self.cancel.clicked(lambda button: self.reject())
    
          # addding action when form is rejected 
          self.ok.clicked(self.getInfo)
    
          # creating a vertical layout 
          mainLayout = QVBoxLayout() 
    
          # adding form group box to the layout 
          mainLayout.addWidget(self.formGroupBox) 
    
          # adding button box to the layout 
          mainLayout.addWidget(self.buttonBox) 
    
          # setting lay out 
          self.setLayout(mainLayout) 
    
      # get info method called when form is accepted 
      def getInfo(self): 
    
          # printing the form information 
          print("Xstart : {0}".format(self.nameLineEdit1.text)) 
          print("Ystart : {0}".format(self.nameLineEdit2.text))         
          print("Xend : {0}".format(self.nameLineEdit3.text)) 
          print("Yend : {0}".format(self.nameLineEdit4.text)) 
          # closing the window 
          self.close()
    
    GUI_Klayout = Dialog(pya.Application.instance().main_window())
    GUI_Klayout.exec_()
    
  • edited February 2021

    @sebastian Thanks a lot for your assistance.

    And yes, KLayout's Qt isn't pyqt. The reason is that I started with Ruby about ten years ago and qtruby (the pyqt equivalent, which AFAIK isn't maintained any longer) was not evolved. After integrating Python I looked at pyqt but found it's difficult to integrate with a C++ application. Hence the homegrown solution.

    Anywhy, but @tagger5896, is there a reason you importing tkinter? And "GuiDialog" isn't really a Dialog - it's merely a function that tries a couple of modal single-value query dialogs, right? The other Dialog looks much more like a real Qt dialog :)

    Regards,

    Matthias

  • Matthias
    it was a cut and paste from Spyder I had been using EasyGui :)

Sign In or Register to comment.