I am trying to work with pyqt and create a "UI". The main idea is to plot a graph/curve and clip the selected area with placing the widget (blue area) and clicking on the button: clip.
I tried to write a function def clicked(self):, which should change the data frame and update the curve. The idea: I am selecting an area, which creates a high (self.hi) and low value (self.lo). I am creating a new list filteredto select the index, which I want to drop later from my data frame. Is there a way to write a better function? How should I approach to this problem?
The .csv Date is online:
https://gigamove.rwth-aachen.de/de/download/ba5527c1f92270bc3235bfbd05c3a5d9
Best
import pandas as pd
import numpy as np
import glob
from pyqtgraph.Qt import QtGui, QtCore
import numpy as np
import pyqtgraph as pg
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
class MyWindow(QMainWindow):
Liste = ["BetaPinen4MSAlleParikel.csv"]#glob.glob("*.csv")
df = pd.read_csv(Liste[0])
def __init__(self):
super(MyWindow, self).__init__()
#self. setGeometry(200, 200, 300, 300)
self.setWindowTitle("Spectrum analysis")
self.initUI()
self.hi = 0
self.setCentralWidget(self.cw)
self.l.addWidget(self.pw3)
#Plot###########
#self.graphWidget.setBackground('w')
self.curve_plot()
self.lr.sigRegionChanged.connect(self.regionUpdate)
self.pw3.addItem(self.lr)
self.l.addWidget(self.b1)
self.cw.setLayout(self.l)
self.show()
def curve_plot(self):
self.curve = self.pw3.plot(MyWindow.df["Energy"],MyWindow.df["df1.1"], clickable=True)
self.curve.curve.setClickable(True)
self.curve.setPen('w') ## white pen
self.curve.setShadowPen(pg.mkPen((70,70,30), width=6, cosmetic=True))
def regionUpdate(self,regionItem):
self.lo,self.hi = regionItem.getRegion()
print(round(self.lo,2), round(self.hi,2))
def initUI(self): #All the stuff on the window in this function
self.label = QtWidgets.QLabel(self)
self.label.setText("my first label!")
self.label.move(50,50)
self.b1 = QtWidgets.QPushButton(self)
self.b1.setText("Clip")
self.b1.clicked.connect(self.clicked)
self.cw = QtWidgets.QWidget()
self.proxy = QtWidgets.QGraphicsProxyWidget()
self.l = QtWidgets.QVBoxLayout()
self.pw3 = pg.PlotWidget()
self.lr = pg.LinearRegionItem([250, 300], movable=True)
def clicked(self):
print(self.lo, self.hi)
List = list(MyWindow.df.index.values)
filtered = [x for x in List if x > self.lo and x < self.hi]
print(filtered)
MyWindow.df.index = MyWindow.df["Energy"]
print(MyWindow.df)
MyWindow.df = MyWindow.df.drop(filtered)
print(MyWindow.df)
self.curve.setData(MyWindow.df["Energy"],MyWindow.df["df1.1"])
self.curve.sigPlotChanged(MyWindow.df)
def window() :
app=pg.mkQApp()
win= MyWindow()
sys.exit(app.exec_())
window()
It took me some time, but I found a solution.
First: I created a new instance with an attribute:
win.curve_plot(name_df="BetaPinen4MSAlleParikel.csv")
Second: I change the function def clicked(self) a bit.
def clicked(self):
self.df = self.df[(self.df.Energy < self.lo) | (self.df.Energy > self.hi)]
self.df = self.df.reset_index()
self.df = self.df.drop(["index"],axis=1)
self.curve.setData(self.df["Energy"],self.df["df1.1"])
Related
I have a complex program in which I need to connect multiple windows. Unfortunately, I seem to be not fully understanding the concept/steps necessary to do this so bonus points if anyone can explain the steps/process well. In my current program, I have a list of items. Once I select them by moving them over to the right list widget, I need them to go to the third window. The third window should be activated by clicking the dots on the second window. The program runs and shows the second window appropriately but the signal/slot connection of the dots button does not work. However, the rest of the code is working because if I switch the toolkit to show the third window, that part is performing as expected. My code is below, and again, no errors are being returned, but clicking the dots button on the second window does nothing.
Also, a question - do I instantiate the third window within the second class, or only within the main window? Again, struggling to fully understand the process and I will need to do this multiple more times.
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QListWidget, QLineEdit, QTextEdit, QGridLayout, QHBoxLayout, QVBoxLayout, QSizePolicy, QFileDialog, QTabWidget, QCheckBox
import PyQt5.QtGui as qtg
import glob
import os
from PyQt5.QtCore import Qt, QSettings
import inspect
from PyQt5 import QtCore
import pandas as pd
import pathlib
import pyreadstat
import json
class ThirdWindow(QWidget):
def __init__(self):
super().__init__()
self.layout = QGridLayout()
self.setLayout(self.layout)
self.allVariables = QListWidget()
self.variablesSelected = QListWidget()
#self.allVariables.insertItem(0, 'Hello')
self.layout.addWidget(self.allVariables, 1,0)
self.layout.addWidget(self.variablesSelected, 1, 1)
def setItems(self, items):
self.allVariables.clear()
for item in items:
self.allVariables.addItem(item)
class SecondWindow(QWidget):
def __init__(self):
super().__init__()
##not sure if I am supposed to instantiate this here or only in the main window class
self.thirdWindow = ThirdWindow()
self.layout = QGridLayout(self)
self.by = QLabel("By")
self.byVariables = QLineEdit()
self.byButton = QPushButton("...")
self.layout.addWidget(self.by, 1, 0)
self.layout.addWidget(self.byVariables, 2, 0)
self.layout.addWidget(self.byButton, 2, 1)
def seconddWindowConnections(self):
self.byButton.clicked.connect(self.show_third_window)
#self.buttons['Toolkit'].clicked.connect(self.show_new_window)
def show_third_window(self):
self.thirdWindow.show()
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# Add a title
self.setWindowTitle("GUI Querying Program")
self.layout = QHBoxLayout()
self.setLayout(self.layout)
self.initUI()
self.setButtonConnections()
self.sw = SecondWindow()
self.tw = ThirdWindow()
def initUI(self):
subLayouts = {}
subLayouts['LeftColumn'] = QGridLayout()
self.layout.addLayout(subLayouts['LeftColumn'],1)
# Buttons
self.buttons = {}
self.buttons['addVariable'] = QPushButton('>')
self.buttons['removeVariable'] = QPushButton('<')
self.buttons['Toolkit'] = QPushButton('Toolkit')
self.variables = QListWidget()
self.selectedVariables = QListWidget()
subLayouts['LeftColumn'].addWidget(self.variables, 7,0,4,1)
subLayouts['LeftColumn'].addWidget(self.selectedVariables, 7,1,4,1)
subLayouts['LeftColumn'].addWidget(self.buttons['addVariable'], 10,0,1,1)
subLayouts['LeftColumn'].addWidget(self.buttons['removeVariable'], 10,1,1,1)
subLayouts['LeftColumn'].addWidget(self.buttons['Toolkit'], 11,1,1,1)
names = ['apple', 'banana', 'Cherry']
self.variables.insertItems(0, names)
def setButtonConnections(self):
self.buttons['addVariable'].clicked.connect(self.add_variable)
self.buttons['Toolkit'].clicked.connect(self.show_new_window)
self.buttons['Toolkit'].clicked.connect(self.add_selected_variables)
def add_variable(self):
for item in self.variables.selectedItems():
self.selectedVariables.addItem(item.clone())
def show_new_window(self):
self.sw.show()
def add_selected_variables(self):
items = []
for i in range(self.selectedVariables.count()):
items.append(self.selectedVariables.item(i).clone())
self.tw.setItems(items)
if __name__ == "__main__":
import sys
app = QApplication([])
mw = MainWindow()
mw.show()
app.exec()
The main issue with your code is that secondWindowConnections is never called so the button actually does nothing. I corrected that and fixed a few other issues I found in my example below. I left out the bits where I made no changes and all the changes I did make I made inline notes explaining them:
class SecondWindow(QWidget):
def __init__(self):
super().__init__()
self.thirdWindow = None # dont initialize until neccessary
self.thirdWindowItems = []
self.layout = QGridLayout(self)
self.by = QLabel("By")
self.byVariables = QLineEdit()
self.byButton = QPushButton("...")
self.layout.addWidget(self.by, 1, 0)
self.layout.addWidget(self.byVariables, 2, 0)
self.layout.addWidget(self.byButton, 2, 1)
self.secondWindowConnections() # Run this to setup the
# signal for the third window.
def secondWindowConnections(self): # this had a typo
self.byButton.clicked.connect(self.show_third_window)
def show_third_window(self):
if self.thirdWindow is None: # if window has been created yet
self.thirdWindow = ThirdWindow() # create window
if not self.thirdWindow.isVisible(): # if window is showing
self.thirdWindow.show() # show window
self.thirdWindow.setItems(self.thirdWindowItems) # send items to window
def send_items(self, items): # this is to collect the variable that
self.thirdWindowItems = items # move to the third window
class MainWindow(QWidget):
def __init__(self):
super().__init__()
# Add a title
self.setWindowTitle("GUI Querying Program")
self.layout = QHBoxLayout()
self.setLayout(self.layout)
self.initUI()
self.setButtonConnections()
self.sw = None # dont initialize until neccessary.
def initUI(self):
subLayouts = {}
subLayouts['LeftColumn'] = QGridLayout()
self.layout.addLayout(subLayouts['LeftColumn'],1)
self.buttons = {}
self.buttons['addVariable'] = QPushButton('>')
self.buttons['removeVariable'] = QPushButton('<')
self.buttons['Toolkit'] = QPushButton('Toolkit')
self.variables = QListWidget()
self.selectedVariables = QListWidget()
subLayouts['LeftColumn'].addWidget(self.variables, 7,0,4,1)
subLayouts['LeftColumn'].addWidget(self.selectedVariables, 7,1,4,1)
subLayouts['LeftColumn'].addWidget(self.buttons['addVariable'], 10,0,1,1)
subLayouts['LeftColumn'].addWidget(self.buttons['removeVariable'], 10,1,1,1)
subLayouts['LeftColumn'].addWidget(self.buttons['Toolkit'], 11,1,1,1)
names = ['apple', 'banana', 'Cherry']
self.variables.insertItems(0, names)
def setButtonConnections(self):
self.buttons['addVariable'].clicked.connect(self.add_variable)
self.buttons['Toolkit'].clicked.connect(self.show_new_window)
# self.buttons['Toolkit'].clicked.connect(self.add_selected_variables)
# only use one connnect slot
def add_variable(self):
for item in self.variables.selectedItems():
self.selectedVariables.addItem(item.clone())
def show_new_window(self):
if self.sw is None: # check if window has been constructed
self.sw = SecondWindow() # construct window
if not self.sw.isVisible(): # If winow is not showing
self.sw.show() # show window
self.sw.send_items(self.add_selected_variables()) # send selected
# variables to second window
def add_selected_variables(self):
items = []
for i in range(self.selectedVariables.count()):
items.append(self.selectedVariables.item(i).clone())
# self.tw.setItems(items) ... self.tw doesnt exist so return them
return items
I'm trying to create an animation to hide unselected rows in a QTableWidget.
I want the height of the rows to decrease until it is 0, for a smoother transition.
I found the following in C++ that does exactly what I'm trying to achieve, but I cannot get the same result in Python: https://forum.qt.io/topic/101437/animate-qtablewidget/4
I noticed they use Q_PROPERTY, but I honestly do not understand how it works...
Here what I came up for now (the animation is not working):
`
import sys
from PySide2.QtGui import *
from PySide2.QtWidgets import *
from PySide2.QtCore import *
class Example(QWidget):
def __init__(self):
super().__init__()
self.resize(600,200)
self.initUI()
def initUI(self):
layout = QHBoxLayout()
self.table = QTableWidget()
self.table.setColumnCount(3)
tableLabels = ["First Name", "Surname", "Age"]
self.table.setHorizontalHeaderLabels(tableLabels)
self.table.setRowCount(3)
self.table.verticalHeader().setMinimumSectionSize(1)
users = {
'0': ["peter", "parker", "19"],
'1': ["bruce", "banner", "42"],
'2': ["barry", "allen", "35"]
}
for row, data in users.items():
for column, value in enumerate(data):
self.table.setItem(int(row), column, QTableWidgetItem(value))
button1 = QPushButton("Hide")
button1.clicked.connect(lambda: self.hide_row())
layout.addWidget(self.table)
layout.addWidget(button1)
self.setLayout(layout)
self.show()
def hide_row(self):
for i in [x for x in range(self.table.rowCount()) if x != self.table.currentRow()]:
self.rowHeight = QPropertyAnimation(self.table.item(i, 0), b"geometry")
self.rowHeight.setDuration(400)
self.rowHeight.setStartValue(QRect(0, 0, 0, self.table.rowHeight(i)))
self.rowHeight.setEndValue(QRect(0, 0, 0, 0))
self.rowHeight.start()
def main():
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
`
Any idea how to achieve this goal in Python?
A Qt animation requires that the parent (or target, in the case of a Property Animation) inherits from QObject, and table widget items do not.
Also, the geometry property should exist for the target object, and items do not have such a property.
The solution is to use a QVariantAnimation and use the valueChanged signal to set the row height on the table.
class Example(QWidget):
def __init__(self):
super().__init__()
self.resize(600,200)
self.initUI()
self.animation = QVariantAnimation(self)
self.animation.setDuration(400)
self.animation.valueChanged.connect(self.animationChanged)
self.animation.finished.connect(self.finished)
def animationChanged(self, height):
self.table.setRowHeight(self.currentRow, height)
def finished(self):
self.table.setRowHidden(self.currentRow, True)
# reset the height, so that we can use it as a "stored" value in case
# we want to show the row again
self.table.setRowHeight(self.currentRow, self.currentHeight)
def hide_row(self):
# ignore if the animation is already resizing a row
if self.animation.state():
return
self.currentRow = self.table.currentRow()
self.currentHeight = self.table.rowHeight(self.currentRow)
self.animation.setStartValue(self.currentHeight)
self.animation.setEndValue(1)
self.animation.start()
# ...
I used this question and tried to use it to do fast live plotting of many subplots.
Unfortunately it is very difficult for me to understand the code and thus I have problems changing it for my needs.
I wanted to create a subplot of 2x2 matrices with 10x10 pixels. Right now I am getting the following:
The code looks like that:
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import numpy as np
import time
import sys
class App(QtGui.QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent)
#### Create Gui Elements ###########
self.mainbox = QtGui.QWidget()
self.setCentralWidget(self.mainbox)
self.mainbox.setLayout(QtGui.QVBoxLayout())
self.canvas = pg.GraphicsLayoutWidget()
self.mainbox.layout().addWidget(self.canvas)
self.label = QtGui.QLabel()
self.mainbox.layout().addWidget(self.label)
self.view = self.canvas.addViewBox()
self.view.setAspectLocked(True)
self.view.setRange(QtCore.QRectF(0, 0, 50, 50))
self.img = []
for i in range(4):
self.img.append(pg.ImageItem(None, border="w"))
self.canvas.nextRow()
self.view.addItem(self.img[i])
self._update()
def _update(self):
for i in range(4):
self.data = np.random.rand(10,10)
self.img[i].setImage(self.data)
QtCore.QTimer.singleShot(1, self._update)
def sensor_data(n_sensors, x_res, y_res):
return np.random.rand(n_sensors, x_res, y_res)
if __name__ == '__main__':
while True:
# Get sensor data
data = sensor_data(4, 10, 10)
# Pass data to live plot function?
app = QtGui.QApplication(sys.argv)
thisapp = App()
thisapp.show()
sys.exit(app.exec_())
Can someone please show me what I'm doing wrong?
You have only built a single ViewBox and in it you are adding the items and that causes the problem, what you must do is create several ViewBox and add an item as I show you next:
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import numpy as np
class App(QtGui.QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent)
self.mainbox = QtGui.QWidget()
self.setCentralWidget(self.mainbox)
self.canvas = pg.GraphicsLayoutWidget()
self.label = QtGui.QLabel()
lay = QtGui.QVBoxLayout(self.mainbox)
lay.addWidget(self.canvas)
lay.addWidget(self.label)
self.img_items = []
for i in range(4):
view = self.canvas.addViewBox()
view.setAspectLocked(True)
view.setRange(QtCore.QRectF(0, 0, 10, 10))
it = pg.ImageItem(None, border="w")
view.addItem(it)
self.img_items.append(it)
self.canvas.nextRow()
timer = QtCore.QTimer(self, interval=1)
timer.timeout.connect(self._update)
timer.start()
def _update(self):
for item in self.img_items:
data = np.random.rand(10, 10)
item.setImage(data)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
thisapp = App()
thisapp.show()
sys.exit(app.exec_())
Update:
NxN
n = 2
for i in range(n):
for j in range(n):
view = self.canvas.addViewBox(i, j)
view.setAspectLocked(True)
view.setRange(QtCore.QRectF(0, 0, 10, 10))
it = pg.ImageItem(None, border="w")
view.addItem(it)
self.img_items.append(it)
Update:
If you want to obtain data within a while True you must do it in a new thread to avoid the GUI being blocked, you must also give a small sleep so that the GUI can be updated:
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import numpy as np
def sensor_data(n_sensors, x_res, y_res):
return np.random.rand(n_sensors, x_res, y_res)
class Thread(QtCore.QThread):
dataChanged = QtCore.pyqtSignal(np.ndarray)
def run(self):
while True:
data = sensor_data(4, 10, 10)
self.dataChanged.emit(data)
QtCore.QThread.msleep(10)
class App(QtGui.QMainWindow):
def __init__(self, parent=None):
super(App, self).__init__(parent)
self.mainbox = QtGui.QWidget()
self.setCentralWidget(self.mainbox)
self.canvas = pg.GraphicsLayoutWidget()
self.label = QtGui.QLabel()
lay = QtGui.QVBoxLayout(self.mainbox)
lay.addWidget(self.canvas)
lay.addWidget(self.label)
self.img_items = []
n = 2
for i in range(n):
for j in range(n):
view = self.canvas.addViewBox(i, j)
view.setAspectLocked(True)
view.setRange(QtCore.QRectF(0, 0, 10, 10))
it = pg.ImageItem(None, border="w")
view.addItem(it)
self.img_items.append(it)
#QtCore.pyqtSlot(np.ndarray)
def update_data(self, data):
for i, v in enumerate(data):
self.img_items[i].setImage(v)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
thisapp = App()
thread = Thread()
thread.dataChanged.connect(thisapp.update_data)
thread.start()
thisapp.show()
sys.exit(app.exec_())
Following code creates a Widget with a Button and a Progressbar. When Button is pressed and Progressbar reaches 100%, 3 plots are shown (by Matplotlib.pyplot):
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import matplotlib.pyplot as plt
import pandas as pd
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.setGeometry(500, 300, 820, 350)
self.setWindowTitle("Program")
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('Load', self)
self.btn4.move(btnposx,btnposy+220)
self.btn4.released.connect(self.thread)
#ProgressBar
self.pb = QProgressBar(self)
self.pb.move(btnposx+150,btnposy+220)
self.pb.resize(470,27)
self.show()
#pyqtSlot(float)
def load(self, val):
self.pb.setValue(val)
#pyqtSlot(object)
def plot(self, pq):
pq.plot(grid = 1)
plt.show()
def thread(self):
self.thread_ = Thread()
self.thread_.pb_signal.connect(self.load, Qt.QueuedConnection)
self.thread_.plot_signal.connect(self.plot, Qt.QueuedConnection)
self.thread_.start()
class Thread(QThread):
pb_signal = pyqtSignal(float)
plot_signal = pyqtSignal(object)
def __init__(self, *args, **kwargs):
QThread.__init__(self, *args, **kwargs)
def __del__(self):
self.wait()
#pyqtSlot()
def run(self):
val = 0
self.pb_signal.emit(20)
l = range(50000000)
for i in l:
val += 1
self.pb_signal.emit(60)
self.pb_signal.emit(100)
pq = pd.DataFrame(data = {'col1':[1,2,3,4,5,6], 'col2':[6,5,4,3,2,1]})
self.plot_signal.emit(pq)
self.plot_signal.emit(pq)
self.plot_signal.emit(pq)
return
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
How do I do the exact same Thing with FigureCanvas? I don't want to make one window, in that 3 plots are embedded but 3 seperate figures. The Information online about how to use FigureCanvas this way is very scarce.
FigureCanvas is a specialized QWidget that can contain a Figure of matplotlib, and in that Figure you can make the plots, so the solution is to create one for each emission, in addition to that the plotting functions have an additional argument that receives the axes where it will be drawn, so you must pass the axes created inside Figure:
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import pandas as pd
from matplotlib.backends.backend_qt4agg import (
FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure
class App(QMainWindow):
def __init__(self):
super(App, self).__init__()
self.setGeometry(500, 300, 820, 350)
self.setWindowTitle("Program")
#Buttons
btnposx = 30
btnposy = 50
self.btn4 = QPushButton('Load', self)
self.btn4.move(btnposx,btnposy+220)
self.btn4.released.connect(self.thread)
#ProgressBar
self.pb = QProgressBar(self)
self.pb.move(btnposx+150,btnposy+220)
self.pb.resize(470,27)
self.canvas = []
self.show()
#pyqtSlot(float)
def load(self, val):
self.pb.setValue(val)
#pyqtSlot(object)
def plot(self, pq):
cv = FigureCanvas(Figure(figsize=(5, 3)))
ax = cv.figure.subplots()
pq.plot(grid = 1, ax=ax)
cv.show()
# avoid garbage collector
self.canvas.append(cv)
def thread(self):
self.thread_ = Thread()
self.thread_.pb_signal.connect(self.load, Qt.QueuedConnection)
self.thread_.plot_signal.connect(self.plot, Qt.QueuedConnection)
self.thread_.start()
class Thread(QThread):
pb_signal = pyqtSignal(float)
plot_signal = pyqtSignal(object)
def __del__(self):
self.wait()
#pyqtSlot()
def run(self):
val = 0
self.pb_signal.emit(20)
l = range(50000000)
for i in l:
val += 1
self.pb_signal.emit(60)
self.pb_signal.emit(100)
pq = pd.DataFrame(data = {'col1':[1,2,3,4,5,6], 'col2':[6,5,4,3,2,1]})
self.plot_signal.emit(pq)
self.plot_signal.emit(pq)
self.plot_signal.emit(pq)
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = App()
ex.show()
sys.exit(app.exec_())
Note: only the list has been created to prevent the garbage collector from deleting the plots
I am pretty new at python but currently I am getting some problem here with the part where I am unable to get my stuff fit within the width of the window.
I am trying to set it in such a way that it is:
Eg. Name Button
by the way, I am using Maya to integrate and run my stuff.
If I set it to central, it fits but it is all over the place as I only wanted it to occupy a portion only. So are there any ways for me to fit it nicely into it?
By the way, if its possible, can it be done using my current codings?
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sip
import maya.OpenMayaUI as mui
import os
class MainWindow(QMainWindow):
def __init__(self, parent = None):
QMainWindow.__init__(self,parent)
self.resize(400,800)
self.setWindowTitle("GetShots")
self.pubDock = SetShotInfo()
self.pubDW = QDockWidget(self.tr(""), self)
self.pubDW.setWidget(self.pubDock)
# self.setCentralWidget(self.pubDW)
def getMayaWindow():
ptr = mui.MQtUtil.mainWindow()
return sip.wrapinstance(long(ptr), QObject)
def main():
global app
global form
app = qApp
form = MainWindow(getMayaWindow())
form.show()
class GetShot(QFrame):
def __init__(self, parent = None, display=None):
QFrame.__init__(self, parent)
self.createWidgets()
self.createLayout()
def createWidgets(self):
self.showLabel = QLabel('Show')
self.showName = QLineEdit()
self.showName.setText(str(os.environ['SHOW']))
self.shotLabel = QLabel('Shot Filter')
self.shotName = QLineEdit()
self.showButton = QPushButton('Set Show')
self.showButton.setMaximumWidth(200)
self.shotButton = QPushButton('Filter Shots')
self.shotButton.setMaximumWidth(200)
self.rootLabel = QLabel('Change Root')
self.rootButton = QComboBox()
def createLayout(self):
# Sets the Layout of Show and Shot
setShowLayout = QHBoxLayout()
setShowLayout.addWidget(self.showLabel)
setShowLayout.addWidget(self.showName)
setShowLayout.addWidget(self.showButton)
setShotLayout = QHBoxLayout()
setShotLayout.addWidget(self.shotLabel)
setShotLayout.addWidget(self.shotName)
setShotLayout.addWidget(self.shotButton)
# Sets the Change Root Layout
chgRootLayout = QHBoxLayout()
chgRootLayout.addWidget(self.rootLabel)
chgRootLayout.addWidget(self.rootButton)
mainLayout = QVBoxLayout()
mainLayout.addLayout(setShowLayout)
mainLayout.addLayout(setShotLayout)
mainLayout.addLayout(chgRootLayout)
self.setLayout(mainLayout)
if __name__ == '__main__':
main()
You need to use Layouts, combine vertical and horizontal and play with the size policy of the widgets to fit them as you need.
Here's a quick example:
import sys
from PyQt4 import QtCore, QtGui
class ButtonContainer(QtGui.QWidget):
def __init__(self):
super(ButtonContainer, self).__init__()
self.initUI()
def initUI(self):
self.setGeometry( 150, 150, 650, 350)
btn = QtGui.QPushButton('Name button', self)
btn.setSizePolicy( QtGui.QSizePolicy( QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed ) )
vbox = QtGui.QVBoxLayout()
vbox.addWidget( btn )
self.setLayout(vbox)
self.show()
app = QtGui.QApplication(sys.argv)
ex = ButtonContainer()
sys.exit(app.exec_())
The commenters are right in suggesting QtDesigner, if you'd rather code it yourself at least have a mock up ui file where you can play interactively with the layouts and size policies, it's really helpful.