diff --git a/README.md b/README.md index fef78b7..b6cab07 100644 --- a/README.md +++ b/README.md @@ -12,14 +12,20 @@ This is a frontend for the collection of tools used by the zebra. ### How To +##### Installation: ``` pip3 install pyqt5 pip3 install matplotlib python3 ./window.py ``` -
+##### About PyQt +Every UI element (e.g. *Button*) is a *Widget*. +A *Widget* can also have a *Layout* (e.g. *Grid*) +and contain other *Widgets*. + +For example: +A *Tab* widget may contain an empty container widget. +The empty container widget may have the grid layout, +and contain a button on position (0,0) of said grid. -### To Do -+ Add a plot. -+ Add file selection. \ No newline at end of file diff --git a/minor_widgets.py b/minor_widgets.py new file mode 100644 index 0000000..dd8ebe1 --- /dev/null +++ b/minor_widgets.py @@ -0,0 +1,2 @@ +'''''' +from PyQt5.QtWidgets import QWidget \ No newline at end of file diff --git a/oneDimView.py b/oneDimView.py new file mode 100644 index 0000000..41a3fd0 --- /dev/null +++ b/oneDimView.py @@ -0,0 +1,145 @@ +from PyQt5.QtWidgets import QPlainTextEdit, QHBoxLayout, QWidget, QGridLayout, QLabel, QPushButton, QTableWidget, QTableWidgetItem + + +class OneDimView(QWidget): + + + def __init__(self): + ''' Widget containing the entire 2D Mode view. ''' + super().__init__() + + self.grid = QGridLayout() + + self.setLayout(self.grid) + + + self.define_widgets() + self.set_widget_actions() + + + + def define_widgets(self): + ''' Define widgets such as buttons. This must be done before setting widget actions. + Otherwise a widget action might try to modify a widget that is not defined yet.''' + + # add empty label as spacer after buttons + # this has some side effects (i suspect) : + # + when adding the Buttons20, we really mean for it to span from grid position (3,1) to (3,2) + # but to create the correct visual effect it must span also over the invisible spacder column, + # Thus from (3,1) to (3,3). + self.grid.addWidget(QLabel(), 10,10) + self.load_data_button = QPushButton() + self.load_data_button.setText("Load Data File") + self.load_data_button.setMaximumWidth(200) + self.grid.addWidget(self.load_data_button, 0, 0) + + + self.one_d_text = OneDText() + self.grid.addWidget(self.one_d_text, 1,0) + + + self.one_d_table = OneDTable() + self.grid.addWidget(self.one_d_table,0,1, 4,1) + + + self.one_d_visualize = OneDVisualize() + self.grid.addWidget(self.one_d_visualize,0,2,2,2) + + self.buttons20 = Buttons20() + self.grid.addWidget(self.buttons20, 2,0) + + self.buttons30 = Buttons30() + self.grid.addWidget(self.buttons30, 3,0) + + self.buttons32 = Buttons32() + self.grid.addWidget(self.buttons32,3,2) + + def set_widget_actions(self): + pass + + + + +class OneDText(QPlainTextEdit): + def __init__(self): + super().__init__() + self.setMinimumSize(200,200) + self.setPlainText("List of Files:\n+ File 1\n+ File 2") + + + +class OneDTable(QTableWidget): + def __init__(self): + super().__init__() + + self.setSortingEnabled(True) + + self.setRowCount(4) + self.setColumnCount(4) + + self.setMinimumSize(300,200) + + self.setHorizontalHeaderLabels({'h', 'k', 'l'}) + + + + + + + +class Buttons20(QWidget): + + def __init__(self): + super().__init__() + self.hbox = QHBoxLayout() + self.setLayout(self.hbox) + self.searchButton = QPushButton('Search') + self.addButton = QPushButton('Add') + self.substractButton = QPushButton('Substract') + self.hbox.addWidget(self.searchButton) + self.hbox.addWidget(self.addButton) + self.hbox.addWidget(self.substractButton) + + + + +class Buttons30(QWidget): + def __init__(self): + super().__init__() + self.hbox = QHBoxLayout() + self.setLayout(self.hbox) + + + self.integrateButton = QPushButton('Integrate') + self.lorentzButton = QPushButton('Lorentz') + self.absorptionButton = QPushButton('Absorption') + + self.hbox.addWidget(self.integrateButton) + self.hbox.addWidget(self.lorentzButton) + self.hbox.addWidget(self.absorptionButton) + + + +class Buttons32(QWidget): + def __init__(self): + ''' Named after its position in the containing grid: row 3, column 2.''' + super().__init__() + self.grid= QGridLayout() + self.setLayout(self.grid) + self.saveButton = QPushButton('Save') + self.grid.addWidget(self.saveButton,0,0) + self.visualizeButton = QPushButton('Visualize in 2D') + self.grid.addWidget(self.visualizeButton, 0,1) + + + +class OneDVisualize(QPlainTextEdit): + def __init__(self): + super().__init__() + self.setMinimumSize(200,200) + self.setPlainText('Placeholder\nfor OneDVisualize().') + + + + + diff --git a/tab.py b/tab.py new file mode 100644 index 0000000..d4fd389 --- /dev/null +++ b/tab.py @@ -0,0 +1,94 @@ + +import sys +from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QWidget, QAction, QTabWidget ,QVBoxLayout +from PyQt5.QtGui import QIcon +from PyQt5.QtCore import pyqtSlot + +class App(QMainWindow): + + def __init__(self): + ''' Everything is used with `self.` so it can be easily accessed in any function. + ''' + super().__init__() + self.title = 'PyQt5 tabs - pythonspot.com' + self.left = 0 + self.top = 0 + self.setWindowTitle(self.title) + self.setGeometry(self.left, self.top, 400, 400) + + self.table_widget = MyTableWidget(self) + self.setCentralWidget(self.table_widget) + + self.modeMenu = self.menuBar().addMenu('Mode') + + self.zebraMenuEntry = QAction('Zebra') + self.zebraMenuEntry.triggered.connect(self.close) + self.modeMenu.addAction(self.zebraMenuEntry) + + self.oneDMenuEntry = QAction('1D Mode') + self.oneDMenuEntry.triggered.connect(self.close) + self.modeMenu.addAction(self.oneDMenuEntry) + + self.twoDMenuEntry = QAction('2D Mode') + self.twoDMenuEntry.triggered.connect(self.close) + self.modeMenu.addAction(self.twoDMenuEntry) + + + + self.show() # once everything is set up, show the window. + + + + + +class MyTableWidget(QWidget): + + def __init__(self, parent): + super(QWidget, self).__init__(parent) + self.layout = QVBoxLayout(self) + + + + + + # Initialize tab screen + self.tabs = QTabWidget() + self.tab1 = QWidget() + self.tab2 = QWidget() + self.tab3 = QWidget() + self.tabs.resize(300 ,200) + + # Add tabs + self.tabs.addTab(self.tab1 ,"Prep Experiment Zebra") + self.tabs.addTab(self.tab2 ,"1D Mode") + self.tabs.addTab(self.tab3, "2D Mode") + + # Create first tab + self.tab1.layout = QVBoxLayout(self) + self.pushButton1 = QPushButton("PyQt5 button") + self.tab1.layout.addWidget(self.pushButton1) + self.tab1.setLayout(self.tab1.layout) + + + # Create second tab + self.tab2.layout = QVBoxLayout(self) + self.tabs2 = QTabWidget() + self.tab21 = QWidget() + self.tabs2.addTab(self.tab21, "hello") + self.tab2.layout.addWidget(self.tabs2) + + + # Add tabs to widget + self.layout.addWidget(self.tabs) + self.setLayout(self.layout) + + @pyqtSlot() + def on_click(self): + print("\n") + for currentQTableWidgetItem in self.tableWidget.selectedItems(): + print(currentQTableWidgetItem.row(), currentQTableWidgetItem.column(), currentQTableWidgetItem.text()) + +if __name__ == '__main__': + app = QApplication(sys.argv) + ex = App() + sys.exit(app.exec_()) \ No newline at end of file diff --git a/test_a_widget.py b/test_a_widget.py new file mode 100644 index 0000000..c324ee4 --- /dev/null +++ b/test_a_widget.py @@ -0,0 +1,35 @@ +import sys + +from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton,QLabel, QVBoxLayout, QWidget + +from two_d_mode import TwoDMode +from one_d_mode import OneDMode, OneDTable + + + +class TestAWidget(QMainWindow): + + + + def __init__(self): + ''' Replace `QPushButton` with any widget you intend to test. + This is meant to be used for quick and easy testing.''' + super().__init__() + + + self.testWidget = OneDMode() + + + + + self.setCentralWidget(self.testWidget) + self.setGeometry(0,0,400,400) + self.setWindowTitle('Test') + self.show() + + + +if __name__ == '__main__': + app = QApplication(sys.argv) + test = TestAWidget() + sys.exit(app.exec()) \ No newline at end of file diff --git a/twoDimView.py b/twoDimView.py new file mode 100644 index 0000000..584f265 --- /dev/null +++ b/twoDimView.py @@ -0,0 +1,130 @@ + +from PyQt5.QtWidgets import QWidget, QGridLayout, QLabel, QPushButton, QAction, QHBoxLayout, QTabWidget, QTableWidget, QPlainTextEdit + + +class TwoDimView(QWidget): + + + + + + + + + + + def __init__(self): + ''' Widget containing the entire Zebra Mode view. ''' + super().__init__() + + self.grid = QGridLayout() + + self.setLayout(self.grid) + + + self.define_widgets() + self.set_widget_actions() + + + + + def define_widgets(self): + ''' Define widgets such as buttons. This must be done before setting widget actions. + Otherwise a widget action might try to modify a widget that is not defined yet.''' + + # add empty label as spacer after buttons + # this has some side effects (i suspect) : + # + when adding the Buttons20, we really mean for it to span from grid position (3,1) to (3,2) + # but to create the correct visual effect it must span also over the invisible spacder column, + # Thus from (3,1) to (3,3). + self.grid.addWidget(QLabel(), 10,10) + self.load_data_button = QPushButton() + self.load_data_button.setText("Load Data File") + self.load_data_button.setMaximumWidth(200) + self.grid.addWidget(self.load_data_button, 1, 0) + + + self.one_d_text = OneDText() + self.grid.addWidget(self.one_d_text, 0,0) + + + self.one_d_table = OneDTable() + self.grid.addWidget(self.one_d_table,0,1) + + self.one_d_visualize = OneDVisualize() + self.grid.addWidget(self.one_d_visualize,0,2) + + + + self.buttons20 = Buttons20() + self.grid.addWidget(self.buttons20, 2,0) + + self.buttons30 = Buttons30() + self.grid.addWidget(self.buttons30, 3,0) + + + + def set_widget_actions(self): + pass + + + + +class OneDText(QPlainTextEdit): + def __init__(self): + super().__init__() + self.setMinimumSize(200,200) + self.setPlainText("List of Files:\n+ File 1\n+ File 2") + + + +class OneDTable(QTableWidget): + def __init__(self): + super().__init__() + + self.setSortingEnabled(True) + + self.setRowCount(4) + self.setColumnCount(4) + + self.setMinimumSize(300,200) + + self.setHorizontalHeaderLabels({'h', 'k', 'l'}) + + + +class OneDVisualize(QPlainTextEdit): + def __init__(self): + super().__init__() + self.setMinimumSize(200,200) + self.setPlainText('Placeholder\nfor OneDVisualize().') + + +class Buttons20(QWidget): + + def __init__(self): + super().__init__() + self.hbox = QHBoxLayout() + self.setLayout(self.hbox) + self.sortButton = QPushButton('Sort') + self.selectButton = QPushButton('Select') + self.optimizeButton = QPushButton('Optimize') + self.hbox.addWidget(self.sortButton) + self.hbox.addWidget(self.selectButton) + self.hbox.addWidget(self.optimizeButton) + + + + +class Buttons30(QWidget): + def __init__(self): + super().__init__() + self.hbox = QHBoxLayout() + self.setLayout(self.hbox) + + + self.runButton = QPushButton('Run') + self.saveButton = QPushButton('Save') + + self.hbox.addWidget(self.runButton) + self.hbox.addWidget(self.saveButton) \ No newline at end of file diff --git a/welcomeView.py b/welcomeView.py new file mode 100644 index 0000000..42569b6 --- /dev/null +++ b/welcomeView.py @@ -0,0 +1,22 @@ + + + +from PyQt5.QtWidgets import QPlainTextEdit, QVBoxLayout, QHBoxLayout, QWidget, QGridLayout, QLabel, QPushButton, QTableWidget, QTableWidgetItem + +from PyQt5.QtGui import QPixmap + + +class WelcomeView(QWidget): + + def __init__(self): + super().__init__() + self.vbox = QVBoxLayout() + self.setLayout(self.vbox) + + self.zebraLabel = QLabel() + zebraImage = QPixmap('zebra.png') + self.zebraLabel.setPixmap(zebraImage) + self.vbox.addWidget(self.zebraLabel) + + self.note = QLabel('Please select a Mode.') + self.vbox.addWidget(self.note) \ No newline at end of file diff --git a/window.py b/window.py index 4563904..2a9f6ac 100644 --- a/window.py +++ b/window.py @@ -4,6 +4,13 @@ from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QMainWindow, QGr from plot_canvas import PlotCanvas class Window(QMainWindow): + ''' + How it works: + First a window is created. + Then all the widgets (buttons, sliders, plots) are added to the window and hidden. + Finally depending on what view is requested widgets are shown or hidden. + This way we work around the need for tabs and maintain a quick and simple UI. + ''' def __init__(self): super().__init__() diff --git a/zebra.png b/zebra.png new file mode 100644 index 0000000..cae9833 Binary files /dev/null and b/zebra.png differ diff --git a/zebra.py b/zebra.py new file mode 100644 index 0000000..bdb6ed5 --- /dev/null +++ b/zebra.py @@ -0,0 +1,95 @@ +import sys + +from PyQt5.QtWidgets import QMainWindow, QApplication, QPushButton, QGraphicsPixmapItem, QLabel,QWidget, QVBoxLayout, QAction +from twoDimView import TwoDimView +from oneDimView import OneDimView +from welcomeView import WelcomeView +from zebraView import ZebraView + + + + +class Zebra(QMainWindow): + + + def __init__(self): + ''' The main window of the Zebra application.''' + super().__init__() + + # Set the main container. + self.container = QWidget(self) + self.setCentralWidget(self.container) + + # Set the main layout. + self.vbox = QVBoxLayout() + self.container.setLayout(self.vbox) + + # Add things. + self.addViews() + self.mainMenu() + + # Finalize settings and show. + self.setGeometry(0,0,0,0) + self.setWindowTitle('Zebra') + self.show() + + + def addViews(self): + ''' Add the three views.''' + self.welcomeView = WelcomeView() + self.vbox.addWidget(self.welcomeView) + self.welcomeView.setHidden(False) + + self.zebraView = ZebraView() + self.vbox.addWidget(self.zebraView) + self.zebraView.setHidden(True) + + self.oneDimView = OneDimView() + self.vbox.addWidget(self.oneDimView) + self.oneDimView.setHidden(True) + + self.twoDimView = TwoDimView() + self.vbox.addWidget(self.twoDimView) + self.twoDimView.setHidden(True) + + + def mainMenu(self): + ''' Set up the main menu.''' + self.modeMenu = self.menuBar().addMenu('Mode') + + self.zebraMenuEntry = QAction('Zebra') + self.zebraMenuEntry.triggered.connect(lambda: self.showView('zebra')) + self.modeMenu.addAction(self.zebraMenuEntry) + + self.oneDMenuEntry = QAction('1D Mode') + self.oneDMenuEntry.triggered.connect(lambda: self.showView('1D')) + self.modeMenu.addAction(self.oneDMenuEntry) + + self.twoDMenuEntry = QAction('2D Mode') + self.twoDMenuEntry.triggered.connect(lambda: self.showView('2D')) + self.modeMenu.addAction(self.twoDMenuEntry) + + + + def showView(self, view): + self.welcomeView.setHidden(True) + self.zebraView.setHidden(True) + self.oneDimView.setHidden(True) + self.twoDimView.setHidden(True) + + if view == 'zebra': + self.zebraView.setHidden(False) + elif view == '1D': + self.oneDimView.setHidden(False) + elif view =='2D': + self.twoDimView.setHidden(False) + else: + pass + + + + +if __name__ == '__main__': + app = QApplication(sys.argv) + test = Zebra() + sys.exit(app.exec()) \ No newline at end of file diff --git a/zebra.uxf b/zebra.uxf new file mode 100644 index 0000000..8e1733f --- /dev/null +++ b/zebra.uxf @@ -0,0 +1,799 @@ + + + 8 + + UMLClass + + 808 + 0 + 168 + 24 + + Prep Experiment Zebra +bg=#777777 +halign=left + + + + UMLClass + + 808 + 24 + 136 + 24 + + Load Crystal File +bg=#BBBBBB +halign=left + + + + UMLClass + + 808 + 48 + 160 + 24 + + Load Instrument File +bg=#BBBBBB +halign=left + + + + UMLClass + + 808 + 96 + 160 + 24 + + Sector Nuc +bg=#BBBBBB +halign=left + + + + UMLClass + + 1208 + 280 + 272 + 352 + + Table +1.1.3 + +generated by code +(called by button prepare sector) + +columns= {h,k,l} and others (see 1.1.4) + +1.1.4 +sort ascending , descending + + + + Relation + + 960 + 96 + 392 + 184 + + lt=<. + 470.0;210.0;250.0;130.0;10.0;10.0 + + + UMLClass + + 1184 + 264 + 320 + 424 + + +layer=-1 +fg=blue + + + + UMLClass + + 1208 + 640 + 56 + 32 + + Sort + + + + UMLClass + + 1264 + 640 + 64 + 32 + + Select + + + + UMLClass + + 1328 + 640 + 80 + 32 + + Optimize + + + + UMLClass + + 1408 + 640 + 72 + 32 + + Save + + + + UMLClass + + 808 + 120 + 160 + 24 + + Sector Mag +halign=left +bg=#BBBBBB + + + + UMLClass + + 1552 + 280 + 264 + 352 + + Table +1.1.5-6 + +columns= {h,k,l} and others + + + + UMLClass + + 1528 + 264 + 320 + 424 + + +layer=-1 +fg=blue + + + + UMLClass + + 1552 + 640 + 56 + 32 + + Run + + + + Relation + + 960 + 120 + 728 + 160 + + lt=<. + 890.0;180.0;890.0;70.0;10.0;10.0 + + + UMLClass + + 1608 + 640 + 56 + 32 + + Sort + + + + UMLClass + + 1664 + 640 + 80 + 32 + + Optimize + + + + UMLClass + + 1744 + 640 + 72 + 32 + + Save + + + + UMLClass + + 816 + 1056 + 328 + 352 + + Table +halign=left + +File 1 ID | X | Y +FILE 2 ID | X | Y + +FILE 1+2 ID | X | Y + + + + + UMLClass + + 480 + 696 + 504 + 104 + + 1D Mode +bg=#777777 +halign=left + + + + UMLClass + + 504 + 960 + 136 + 24 + + Load Data +bg=#BBBBBB +halign=left + + + + UMLClass + + 816 + 824 + 160 + 24 + + Manipulate +bg=#BBBBBB +halign=left + + + + UMLClass + + 816 + 848 + 160 + 24 + + Integrate Intensities +bg=#BBBBBB +halign=left + + + + UMLClass + + 1488 + 840 + 160 + 24 + + Visualize Measured Int +bg=#BBBBBB +halign=left + + + + Relation + + 944 + 856 + 136 + 176 + + lt=<. + 10.0;200.0;150.0;150.0;40.0;10.0 + + + UMLClass + + 512 + 1016 + 1000 + 592 + + +layer=-1 + +fg=blue + + + + UMLClass + + 816 + 1448 + 80 + 32 + + Integrate + + + + UMLClass + + 896 + 1448 + 64 + 32 + + Lorentz + + + + UMLClass + + 960 + 1448 + 80 + 32 + + Absorption + + + + UMLClass + + 1896 + 840 + 184 + 24 + + Visualize Parapetric Data +halign=left +bg=#BBBBBB + + + + UMLClass + + 1560 + 1056 + 272 + 352 + + GUI Window???? + + + + UMLClass + + 1536 + 1040 + 320 + 424 + + +layer=-1 +fg=blue + + + + Relation + + 1640 + 848 + 80 + 208 + + lt=<. + 80.0;240.0;30.0;90.0;10.0;10.0 + + + UMLClass + + 1880 + 1040 + 320 + 64 + + +layer=-1 +fg=blue + + + + UMLClass + + 1952 + 1056 + 56 + 32 + + Q-Maps + + + + UMLClass + + 2008 + 1056 + 104 + 32 + + Plot Data Vs + + + + UMLClass + + 2112 + 1056 + 72 + 32 + + Save + + + + Relation + + 2024 + 840 + 72 + 216 + + lt=<. + 10.0;250.0;10.0;210.0;70.0;10.0 + + + UMLClass + + 1072 + 800 + 200 + 24 + + Open File Dialogue +halign=left + + + + Relation + + 960 + 32 + 120 + 48 + + lt=<. + 130.0;10.0;10.0;40.0 + + + UMLClass + + 1064 + 32 + 200 + 24 + + Open File Dialogue +halign=left + + + + Relation + + 936 + 24 + 144 + 32 + + lt=<. + 160.0;20.0;10.0;10.0 + + + UMLClass + + 816 + 1416 + 56 + 32 + + Search + + + + UMLClass + + 872 + 1416 + 64 + 32 + + Add + + + + UMLClass + + 936 + 1416 + 80 + 32 + + Substract + + + + UMLClass + + 1016 + 1416 + 72 + 32 + + Save + + + + UMLClass + + 1896 + 1184 + 136 + 96 + + GUI Window???? + + + + UMLClass + + 2072 + 1184 + 136 + 96 + + GUI Window???? + + + + UMLClass + + 1880 + 1152 + 168 + 160 + + +layer=-1 +fg=blue + + + + UMLClass + + 2056 + 1152 + 168 + 160 + + +layer=-1 +fg=blue + + + + Relation + + 2048 + 1080 + 104 + 88 + + lt=<. + 110.0;90.0;10.0;10.0 + + + Relation + + 1952 + 1080 + 40 + 88 + + lt=<. + 10.0;90.0;30.0;10.0 + + + Text + + 1320 + 736 + 80 + 56 + + Extra Features + + + + Relation + + 736 + 96 + 80 + 136 + + lt=. + 80.0;10.0;10.0;150.0 + + + Text + + 704 + 224 + 80 + 56 + + Button + + + + Relation + + 1432 + 664 + 24 + 72 + + lt=. + 10.0;70.0;10.0;10.0 + + + Text + + 1432 + 728 + 80 + 56 + + Base Feature + + + + Relation + + 1344 + 664 + 24 + 72 + + lt=. + 10.0;70.0;10.0;10.0 + + + Relation + + 1280 + 672 + 64 + 80 + + lt=. + 60.0;80.0;10.0;10.0 + + + Relation + + 1232 + 664 + 96 + 96 + + lt=. + 100.0;100.0;10.0;10.0 + + + UMLClass + + 536 + 1080 + 192 + 160 + + List of Files loaded ++ File 1 ++ File 2 +halign=left + + + + UMLClass + + 1152 + 1056 + 328 + 352 + + +halign=left +visualize +e.g. integration + + + + + + + + + UMLClass + + 1280 + 1456 + 200 + 32 + + Very Special Button + + + + Relation + + 1472 + 1456 + 104 + 48 + + lt=<. + 110.0;10.0;80.0;40.0;10.0;20.0 + + + Relation + + 1472 + 1304 + 552 + 256 + + lt=<. + 670.0;10.0;590.0;300.0;10.0;220.0 + + diff --git a/zebraView.py b/zebraView.py new file mode 100644 index 0000000..81b44ec --- /dev/null +++ b/zebraView.py @@ -0,0 +1,124 @@ + + + +from PyQt5.QtWidgets import QPlainTextEdit, QVBoxLayout, QHBoxLayout, QWidget, QGridLayout, QLabel, QPushButton, QTableWidget, QTableWidgetItem + +from PyQt5.QtGui import QPixmap + + +class ZebraView(QWidget): + + def __init__(self): + ''' Widget containing the entire Zebra Mode view. ''' + super().__init__() + + self.grid = QGridLayout() + + self.setLayout(self.grid) + + + self.define_widgets() + self.set_widget_actions() + + + + + def define_widgets(self): + ''' Define widgets such as buttons. This must be done before setting widget actions. + Otherwise a widget action might try to modify a widget that is not defined yet.''' + + # add empty label as spacer after buttons + # this has some side effects (i suspect) : + # + when adding the Buttons20, we really mean for it to span from grid position (3,1) to (3,2) + # but to create the correct visual effect it must span also over the invisible spacder column, + # Thus from (3,1) to (3,3). + self.grid.addWidget(QLabel(), 10,10) + self.load_data_button = QPushButton() + self.load_data_button.setText("Load Data File") + self.load_data_button.setMaximumWidth(200) + self.grid.addWidget(self.load_data_button, 0, 0) + + + self.one_d_text = OneDText() + self.grid.addWidget(self.one_d_text, 1,0) + + + self.one_d_table = OneDTable() + self.grid.addWidget(self.one_d_table,0,1, 4,1) + + + + self.buttons20 = Buttons20() + self.grid.addWidget(self.buttons20, 2,0) + + self.buttons30 = Buttons30() + self.grid.addWidget(self.buttons30, 3,0) + + + + def set_widget_actions(self): + pass + + + + +class OneDText(QPlainTextEdit): + def __init__(self): + super().__init__() + self.setMinimumSize(200,200) + self.setPlainText("List of Files:\n+ File 1\n+ File 2") + + + +class OneDTable(QTableWidget): + def __init__(self): + super().__init__() + + self.setSortingEnabled(True) + + self.setRowCount(4) + self.setColumnCount(4) + + self.setMinimumSize(300,200) + + self.setHorizontalHeaderLabels({'h', 'k', 'l'}) + + + + + + + +class Buttons20(QWidget): + + def __init__(self): + super().__init__() + self.hbox = QHBoxLayout() + self.setLayout(self.hbox) + self.sortButton = QPushButton('Sort') + self.selectButton = QPushButton('Select') + self.optimizeButton = QPushButton('Optimize') + self.hbox.addWidget(self.sortButton) + self.hbox.addWidget(self.selectButton) + self.hbox.addWidget(self.optimizeButton) + + + + +class Buttons30(QWidget): + def __init__(self): + super().__init__() + self.hbox = QHBoxLayout() + self.setLayout(self.hbox) + + + self.runButton = QPushButton('Run') + self.saveButton = QPushButton('Save') + + self.hbox.addWidget(self.runButton) + self.hbox.addWidget(self.saveButton) + + + + +