I am working through a basic PyQt designer example to create a script to accept two numbers and add them.
I created the calc_ui.py file as:
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_CalculatorUI(object):
def setupUi(self, CalculatorUI):
CalculatorUI.setObjectName(_fromUtf8("CalculatorUI"))
CalculatorUI.resize(219, 134)
self.gridLayout = QtGui.QGridLayout(CalculatorUI)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.labelX = QtGui.QLabel(CalculatorUI)
self.labelX.setObjectName(_fromUtf8("labelX"))
self.gridLayout.addWidget(self.labelX, 0, 0, 1, 1)
self.lineEditX = QtGui.QLineEdit(CalculatorUI)
self.lineEditX.setObjectName(_fromUtf8("lineEditX"))
self.gridLayout.addWidget(self.lineEditX, 0, 1, 1, 1)
self.labelY = QtGui.QLabel(CalculatorUI)
self.labelY.setObjectName(_fromUtf8("labelY"))
self.gridLayout.addWidget(self.labelY, 1, 0, 1, 1)
self.lineEditY = QtGui.QLineEdit(CalculatorUI)
self.lineEditY.setObjectName(_fromUtf8("lineEditY"))
self.gridLayout.addWidget(self.lineEditY, 1, 1, 1, 1)
self.labelZ = QtGui.QLabel(CalculatorUI)
self.labelZ.setObjectName(_fromUtf8("labelZ"))
self.gridLayout.addWidget(self.labelZ, 2, 0, 1, 1)
self.lineEditZ = QtGui.QLineEdit(CalculatorUI)
self.lineEditZ.setReadOnly(True)
self.lineEditZ.setObjectName(_fromUtf8("lineEditZ"))
self.gridLayout.addWidget(self.lineEditZ, 2, 1, 1, 1)
self.buttonCalc = QtGui.QPushButton(CalculatorUI)
self.buttonCalc.setObjectName(_fromUtf8("buttonCalc"))
self.gridLayout.addWidget(self.buttonCalc, 3, 0, 1, 2)
self.retranslateUi(CalculatorUI)
QtCore.QMetaObject.connectSlotsByName(CalculatorUI)
def retranslateUi(self, CalculatorUI):
CalculatorUI.setWindowTitle(_translate("CalculatorUI", "Calculator", None))
self.labelX.setText(_translate("CalculatorUI", "X:", None))
self.labelY.setText(_translate("CalculatorUI", "Y:", None))
self.labelZ.setText(_translate("CalculatorUI", "Z:", None))
self.buttonCalc.setText(_translate("CalculatorUI", "Calculate", None))
My main.py is:
from PyQt4 import QtGui, QtCore
import sys
from calc_ui import Ui_CalculatorUI
class Calculator(Ui_CalculatorUI):
def __init__(self):
Ui_CalculatorUI.__init__(self)
#self.setupUi(self)
self.buttonCalc.clicked.connect(self.handleCalculate)
def handleCalculate(self):
x = int(self.lineEditX.text())
y = int(self.lineEditY.text())
self.lineEditZ.setText(str(x + y))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Calculator()
window.show()
sys.exit(app.exec_())
However, my error is:
AttributeError: 'Calculator' object has no attribute 'buttonCalc'
even though I can see that 'buttonCalc' has been defined in the calc_ui.py file.
I have tried different syntax but running into a wall here.
Qt Designer generate a class to fill a widget, ie is not a widget, you must create a class that inherits from the widget that I take as a template, assume that it is Dialog, then you should call the setupUi() function that fills the widget
class Calculator(QtGui.QDialog, Ui_CalculatorUI):
def __init__(self, parent=None):
QtGui.QDialog.__init__(self, parent)
self.setupUi(self)
self.buttonCalc.clicked.connect(self.handleCalculate)
def handleCalculate(self):
x = int(self.lineEditX.text())
y = int(self.lineEditY.text())
self.lineEditZ.setText(str(x + y))
Output:
Related
I have implemented QUndoStack with QGraphicScene and everything is working like charm with individual QGraphicItem movement/rotation, but when it comes to the multi-items movement, I couldn't find any way to do so, since I didn't find any flag/signal that will be emitted after all selected item position has been changed [ NOT DURING].
Here is a sketch code that will represent my goals.
import sys
from typing import Dict
from PyQt5.QtCore import Qt, QPoint
from PyQt5.QtGui import QPen, QColor, QBrush
from PyQt5.QtWidgets import QApplication, QGraphicsItem, QMainWindow, QGraphicsScene, QGraphicsView, \
QGraphicsEllipseItem, QUndoStack, QUndoCommand
import random
class CustomUndoRedoStack(QUndoStack):
instance = None
def __init__(self):
if not CustomUndoRedoStack.instance:
CustomUndoRedoStack.instance = self
super(CustomUndoRedoStack, self).__init__()
#staticmethod
def get_instance():
return CustomUndoRedoStack.instance
class MovingMultiItemsCommand(QUndoCommand):
def __init__(self, new_items_pos: Dict[QGraphicsItem], old_items_pos: Dict[QGraphicsItem]):
super(MovingMultiItemsCommand, self).__init__()
self.new_items_pos = new_items_pos
self.old_items_pos = old_items_pos
CustomUndoRedoStack.get_instance().push(self)
def undo(self) -> None:
for item in self.old_items_pos:
item.setPos(self.old_items_pos[item])
super(MovingMultiItemsCommand, self).undo()
def redo(self) -> None:
for item in self.new_items_pos:
item.setPos(self.new_items_pos[item])
super(MovingMultiItemsCommand, self).redo()
class CustomQGraphicsEllipseItem(QGraphicsEllipseItem):
def __init__(self, x, y):
super(CustomQGraphicsEllipseItem, self).__init__(x, y, 20, 20)
self.setFlag(QGraphicsItem.ItemIsSelectable)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setPen(QPen(QColor(255, 128, 0), 0.5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
self.setBrush(QBrush(QColor(255, 128, 20, 128)))
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.setDragMode(QGraphicsView.RubberBandDrag)
self._isPanning = False
self._mousePressed = False
self.setCacheMode(QGraphicsView.CacheBackground)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
class MyGraphicsScene(QGraphicsScene):
def __init__(self):
super(MyGraphicsScene, self).__init__()
self.setBackgroundBrush(QBrush(QColor(50, 50, 50)))
self.old_items_pos = {}
self.new_items_pos = {}
# ------- I want something like the following -----------------------------
def selected_items_before_change(self):
for item in self.selectedItems():
self.old_items_pos[item] = item.pos()
def selected_items_after_change(self):
for item in self.selectedItems():
self.new_items_pos[item] = item.pos()
def selected_item_position_changed(self):
"""
This method must be triggered only and only once after selected items position has been changed (NOT WHILE)
"""
MovingMultiItemsCommand(self.new_items_pos, self.old_items_pos)
# ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
class MyMainWindow(QMainWindow):
def __init__(self):
super(MyMainWindow, self).__init__()
self.setWindowTitle("Test")
self.resize(800, 600)
self.gv = MyGraphicsView()
self.gv.setScene(MyGraphicsScene())
self.setCentralWidget(self.gv)
self.populate()
def populate(self):
scene = self.gv.scene()
for i in range(500):
x = random.randint(0, 1000)
y = random.randint(0, 1000)
rect = CustomQGraphicsEllipseItem(x, y)
scene.addItem(rect)
def main():
app = QApplication(sys.argv)
ex = MyMainWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
C++ answers will be good as well, but Python is preferable :)
The mouse movement of selectable items is handled by the graphics scene, starting with its mousePressEvent() and ending with the corresponding mouseReleaseEvent().
This means that you can create a QUndoCommand based on the selected items (if any) after the default implementation of mouse button press/release is called. This will be valid for any movement, including when just one item has been moved.
class ItemMovedUndoCommand(QUndoCommand):
def __init__(self, oldPositions, newPositions):
if len(oldPositions) == 1:
pos = oldPositions.values()[0]
text = 'Item moved to {}x{}'.format(
pos.x(), pos.y())
else:
text = '{} items moved'.format(len(oldPositions))
super().__init__(text)
self.oldPositions = oldPositions
self.newPositions = newPositions
def redo(self):
for item, pos in self.newPositions.items():
item.setPos(pos)
def undo(self):
for item, pos in self.oldPositions.items():
item.setPos(pos)
class CustomQGraphicsEllipseItem(QGraphicsEllipseItem):
def __init__(self, x, y):
super(CustomQGraphicsEllipseItem, self).__init__(-10, -10, 20, 20)
self.setPos(x, y)
self.setFlag(QGraphicsItem.ItemIsSelectable)
self.setFlag(QGraphicsItem.ItemIsMovable)
self.setPen(QPen(QColor(255, 128, 0),
0.5, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
self.setBrush(QBrush(QColor(255, 128, 20, 128)))
class MyGraphicsView(QGraphicsView):
def __init__(self):
super(MyGraphicsView, self).__init__()
self.setDragMode(QGraphicsView.RubberBandDrag)
self._isPanning = False
self._mousePressed = False
self.setCacheMode(QGraphicsView.CacheBackground)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
class MyGraphicsScene(QGraphicsScene):
itemsMoved = pyqtSignal(object, object)
def __init__(self):
super(MyGraphicsScene, self).__init__()
self.setBackgroundBrush(QBrush(QColor(50, 50, 50)))
self.oldPositions = {}
def mousePressEvent(self, event):
super().mousePressEvent(event)
if event.button() == Qt.LeftButton:
self.oldPositions = {i:i.pos() for i in self.selectedItems()}
def mouseReleaseEvent(self, event):
super().mouseReleaseEvent(event)
if event.button() == Qt.LeftButton and self.oldPositions:
self.itemsMoved.emit(self.oldPositions,
{i:i.pos() for i in self.oldPositions.keys()})
self.oldPositions = {}
class MyMainWindow(QMainWindow):
def __init__(self):
super(MyMainWindow, self).__init__()
self.setWindowTitle("Test")
self.resize(800, 600)
self.gv = MyGraphicsView()
self.scene = MyGraphicsScene()
self.gv.setScene(self.scene)
self.setCentralWidget(self.gv)
toolBar = QToolBar()
self.addToolBar(Qt.TopToolBarArea, toolBar)
self.undoStack = QUndoStack()
toolBar.addAction(self.undoStack.createUndoAction(self.scene))
toolBar.addAction(self.undoStack.createRedoAction(self.scene))
self.populate()
self.scene.itemsMoved.connect(self.itemsMoved)
def itemsMoved(self, oldPositions, newPositions):
self.undoStack.push(ItemMovedUndoCommand(oldPositions, newPositions))
def populate(self):
scene = self.gv.scene()
for i in range(500):
x = random.randint(0, 1000)
y = random.randint(0, 1000)
rect = CustomQGraphicsEllipseItem(x, y)
scene.addItem(rect)
Simplest case: How do you add a scrollbar to a tabbed GUI window of fixed size?
Full case: I'm working with a GUI with non-scaleable objects (scenes) in each tabbed frame, and would like the user to still be able to drag-scale the window down on itself (whereby the objects in the scene don't scale, but just get hidden as the window-drag moves over them) and a scroll bar appears. This is the minimal, working code that I've written to help exemplify:
import sys
from pyface.qt import QtGui, QtCore
class P1(QtGui.QWidget):
def __init__(self, parent=None):
super(P1, self).__init__(parent)
layout = QtGui.QGridLayout(self)
layout.setContentsMargins(20,20,20,20) #W,N,E,S
layout.setSpacing(10)
self.label_edge1 = QtGui.QLabel('')
self.label_edge1.setMargin(5)
self.label_edge1.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Sunken)
layout.addWidget(self.label_edge1, 0, 0, 10, 10)
self.label_edge1.show()
self.label_avgVol = QtGui.QLabel('Test')
self.label_avgVol.setMargin(5)
self.label_avgVol.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Sunken)
self.label_avgVol.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter)
layout.addWidget(self.label_avgVol, 0, 0, 1, 10)
self.label_avgVol.show()
self.button1 = QtGui.QPushButton(" Test ", self)
layout.addWidget(self.button1, 8, 8, 1, 1)
self.button1.show()
class P2(QtGui.QWidget):
def __init__(self, parent=None):
super(P2, self).__init__(parent)
layout = QtGui.QGridLayout(self)
layout.setContentsMargins(20,20,20,20)
layout.setSpacing(10)
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setGeometry(50, 50, 500, 500) #(int x, int y, int w, int h)
tab1 = P1(self)
tab2 = P2(self)
self.tabs = QtGui.QTabWidget(self)
self.tabs.resize(250,150)
self.tabs.addTab(tab1, 'Page 1')
self.tabs.addTab(tab2, 'Page 2')
self.setWindowTitle('TABS + SCROLLBAR EXAMPLE')
### Section corrected to include accepted answer, in PyQt4:
self.groupscroll = QtGui.QHBoxLayout()
self.groupscrollbox = QtGui.QGroupBox()
self.MVB = QtGui.QVBoxLayout()
self.MVB.addWidget(self.tabs)
scroll = QtGui.QScrollArea()
widget = QtGui.QWidget(self)
widget.setLayout(QtGui.QHBoxLayout())
widget.layout().addWidget(self.groupscrollbox)
scroll.setWidget(widget)
scroll.setWidgetResizable(True)
self.groupscrollbox.setLayout(self.MVB)
self.groupscroll.addWidget(scroll)
self.setCentralWidget(scroll)
###
self.show()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
I tried something but I use pyqt5 so I modified a little your example.
I'm not sure if it is what you wanted though:
import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class P1(QWidget):
def __init__(self, parent=None):
super(P1, self).__init__(parent)
layout = QGridLayout(self)
layout.setContentsMargins(20,20,20,20) #W,N,E,S
layout.setSpacing(10)
self.label_edge1 = QLabel('')
self.label_edge1.setMargin(5)
self.label_edge1.setFrameStyle(QFrame.Panel | QFrame.Sunken)
layout.addWidget(self.label_edge1, 0, 0, 10, 10)
self.label_edge1.show()
self.label_avgVol = QLabel('Test')
self.label_avgVol.setFixedSize(600,600)
self.label_avgVol.setMargin(5)
self.label_avgVol.setFrameStyle(QFrame.Box | QFrame.Sunken)
self.label_avgVol.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
layout.addWidget(self.label_avgVol, 0, 0, 1, 10)
self.label_avgVol.show()
self.button1 = QPushButton(" Test ", self)
layout.addWidget(self.button1, 8, 8, 1, 1)
self.button1.show()
class P2(QWidget):
def __init__(self, parent=None):
super(P2, self).__init__(parent)
layout = QGridLayout(self)
layout.setContentsMargins(20,20,20,20)
layout.setSpacing(10)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setGeometry(50, 50, 500, 500) #(int x, int y, int w, int h)
tab1 = P1(self)
tab2 = P2(self)
self.tabs = QTabWidget(self)
self.tabs.resize(250,150)
self.tabs.addTab(tab1, 'Page 1')
self.tabs.addTab(tab2, 'Page 2')
self.setWindowTitle('TABS + SCROLLBAR EXAMPLE')
### many trial and error attempts around this attempted setup:
self.groupscroll = QHBoxLayout()
self.groupscrollbox = QGroupBox()
self.MVB = QVBoxLayout()
self.MVB.addWidget(self.tabs)
scroll = QScrollArea()
widget = QWidget(self)
widget.setLayout(QHBoxLayout())
widget.layout().addWidget(self.groupscrollbox)
scroll.setWidget(widget)
scroll.setWidgetResizable(True)
self.groupscrollbox.setLayout(self.MVB)
self.groupscroll.addWidget(scroll)
self.setCentralWidget(scroll)
#self.sbar1 = QtGui.QScrollArea(tab1)
#self.sbar1.setWidget(QtGui.QWidget())
#self.sbar1.setEnabled(True)
###
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
sys.exit(app.exec_())
it gives you the scroll bar (bottom and right) if the inner tab part is too big for the window size:
I have tried to boil down my program to be as simple as possible and still be functional. First is my UI file with the tabs that I want. It has a graph in the Control tab and I want the play button to start the plot.
When I start it I can't get the graph to show up. any help would be appreciated.
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(800, 600)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.tabWidget = QtGui.QTabWidget(self.centralwidget)
self.tabWidget.setGeometry(QtCore.QRect(0, 0, 801, 421))
self.tabWidget.setStyleSheet(_fromUtf8(""))
self.tabWidget.setObjectName(_fromUtf8("tabWidget"))
self.tab_4 = QtGui.QWidget()
self.tab_4.setObjectName(_fromUtf8("tab_4"))
self.tabWidget.addTab(self.tab_4, _fromUtf8(""))
self.tab_2 = QtGui.QWidget()
self.tab_2.setObjectName(_fromUtf8("tab_2"))
self.tabWidget.addTab(self.tab_2, _fromUtf8(""))
self.tab = QtGui.QWidget()
self.tab.setObjectName(_fromUtf8("tab"))
self.pushButton = QtGui.QPushButton(self.tab)
self.pushButton.setGeometry(QtCore.QRect(290, 340, 75, 31))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(_fromUtf8("play_button.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton.setIcon(icon)
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.pushButton_2 = QtGui.QPushButton(self.tab)
self.pushButton_2.setGeometry(QtCore.QRect(460, 340, 75, 31))
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(_fromUtf8("pause_button.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton_2.setIcon(icon1)
self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
self.pushButton_3 = QtGui.QPushButton(self.tab)
self.pushButton_3.setGeometry(QtCore.QRect(630, 340, 75, 31))
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(_fromUtf8("resume_button.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton_3.setIcon(icon2)
self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
self.graphicsView = QtGui.QGraphicsView(self.tab)
self.graphicsView.setGeometry(QtCore.QRect(205, 1, 591, 341))
self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
self.tabWidget.addTab(self.tab, _fromUtf8(""))
self.tab_3 = QtGui.QWidget()
self.tab_3.setObjectName(_fromUtf8("tab_3"))
self.tabWidget.addTab(self.tab_3, _fromUtf8(""))
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(2)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "Calibration", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Material", None))
self.pushButton.setText(_translate("MainWindow", "Start Plot", None))
self.pushButton_2.setText(_translate("MainWindow", "Pause", None))
self.pushButton_3.setText(_translate("MainWindow", "Resume", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Control", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Operator", None))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
The second is my graphing class which does work when I make a gui with code, but I would like to be able to plug it into a program with a ui file.
import sys
import time
import datetime
from PyQt4 import QtCore, QtGui, uic
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import pyqtgraph as pg
import random
from workingraspitab2 import Ui_MainWindow
class Main(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.setupUi(self)
self.graphicsView = QtGui.QStackedWidget()
self.login_widget = LoginWidget(self)
self.graphicsView.addWidget(self.login_widget)
self.pushButton.clicked.connect(self.plotter)#the play button
self.curve = self.login_widget.it1
self.curve2 =self.login_widget.it2
def plotter(self):
self.data =[0]
self.data2 = [0]
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updater)
self.timer.start(0)
print self.data
def updater(self):
self.data.append(self.data[-1]+10*(0.5-random.random()))
self.curve.setData(self.data, pen=pg.mkPen('b', width=1))
self.data2.append(self.data2[-1]+0.1*(0.5-random.random()))
self.curve2.setData(self.data2, pen=pg.mkPen('r', width=1))
print self.data
class LoginWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(LoginWidget, self).__init__(parent)
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
self.plot = pg.PlotWidget(title='Force and Extension vs. Time')
p1 = self.plot.plotItem
p2 = pg.ViewBox()
p1.showAxis('right')
p1.scene().addItem(p2)
p1.getAxis('right').linkToView(p2)
p2.setXLink(p1)
self.plot.getAxis('bottom').setLabel('Time', units='s')
self.plot.getAxis('left').setLabel('Force', units='lbf', color="#0000ff")
p1.getAxis('right').setLabel('Extension', units='in.', color="#ff0000")
def updateViews():
p2.setGeometry(p1.vb.sceneBoundingRect())
p2.linkedViewChanged(p1.vb, p2.XAxis)
updateViews()
p1.vb.sigResized.connect(updateViews)
self.it1 = p1.plot()
self.it2 = pg.PlotCurveItem()
p2.addItem(self.it2)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
Had to put everything in the Main class to get it to work. I was hoping for a more elegant solution. I still cant get the background or foreground to change, but it is working and here is the code:
class Main(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.setupUi(self)
pv = self.graphicsView
pv.setTitle('Force and Extension vs. Time')
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
p1 = pv.plotItem
p2 = pg.ViewBox()
p1.showAxis('right')
p1.scene().addItem(p2)
p1.getAxis('right').linkToView(p2)
p2.setXLink(p1)
pv.getAxis('bottom').setLabel('Time', units='s')
pv.getAxis('left').setLabel('Force', units='lbf', color="#0000ff")
p1.getAxis('right').setLabel('Extension', units='in.', color="#ff0000")
def updateViews():
p2.setGeometry(p1.vb.sceneBoundingRect())
p2.linkedViewChanged(p1.vb, p2.XAxis)
updateViews()
p1.vb.sigResized.connect(updateViews)
self.it1 = p1.plot()
self.it2 = pg.PlotCurveItem()
p2.addItem(self.it2)
self.pushButton.clicked.connect(self.plotter)
self.pushButton_2.clicked.connect(lambda: self.timer.stop())
self.pushButton_3.clicked.connect(self.timer_start)
self.curve = self.it1
self.curve2 = self.it2
I have a Python Tkinter GUI class as following:
import Tkinter as tk
class AppClient(tk.Frame):
def __init__(self, master):
error_class = ErrorClass()
self.val_error_code = error_class.error_message
tk.Frame.__init__(self, master)
self.pack()
##Frame for error message display
error_frame = tk.Frame(self, highlightbackground="violet", highlightcolor="violet", highlightthickness=1, width=600, height = 60, bd= 0)
error_frame.pack(padx = 10, pady = 5, anchor = 'w')
## error code: Label and Entry
tk.Label(error_frame, text = 'Error message').grid(row = 0, column = 0, sticky = 'w')
self.error_code = tk.Entry(error_frame, background = 'white', width = 27)
self.error_code.grid(row = 0, column = 1, sticky = 'w', padx = 5, pady = 5)
def update_error_messsage(self):
self.error_code.delete(0, 'end')
self.error_code.insert(0, self.val_error_code)
if __name__ == '__main__':
root = tk.Tk()
app_client = AppClient(root)
app_client.mainloop()
I want to update the entry field error_code dynamically by using the function update_error_message. The problem is, error message is continuously updated from another class ErrorClass() and I am receiving the error message to my AppClient class by variable error_message.
How can I update the error_code entry filed whenever the value of the variable error_message got updated in another class (ErrorClass())
The simple solution is that you need a reference to your instance of AppClient inside of ErrorClass, and then allow the instance of ErrorClass to pass the new value to the app
For example:
class AppClient(tk.Frame):
def __init__(self, master):
error_class = ErrorClass(self)
...
def update_error_messsage(self, error_code):
self.error_code.delete(0, 'end')
self.error_code.insert(0, error_code)
class ErrorClass():
def __init__(self, app):
self.app = app
def update_error(self):
...
error_code = 42
self.app.update_error_message(error_code)
When I run this code and push my "Preview Barcode" button, I get the following error:
self.input_1.toPlainText()
AttributeError: 'MyWindowClass' object has no attribute 'input_1'
Why am I getting this error?
import sys
from PyQt4 import QtCore, QtGui, uic
_fromUtf8 = QtCore.QString.fromUtf8
class MyWindowClass(QtGui.QMainWindow):
def __init__(self):
super(MyWindowClass, self).__init__()
self.setupUi()
def setupUi(self):
self.setObjectName(_fromUtf8("Form"))
self.resize(559, 340)
previewButton = QtGui.QPushButton(self)
previewButton.setText(QtGui.QApplication.translate("form","Preview\nBarcode", None))
previewButton.setGeometry(QtCore.QRect(140, 20, 151, 101))
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
previewButton.setSizePolicy(sizePolicy)
font = QtGui.QFont()
font.setFamily(_fromUtf8("Papyrus"))
font.setPointSize(18)
font.setBold(True)
font.setWeight(75)
previewButton.setFont(font)
previewButton.setObjectName(_fromUtf8("previewButton"))
input_1 = QtGui.QPlainTextEdit(self)
input_1.setFocus()
input_1.setGeometry(QtCore.QRect(10, 10, 104, 31))
input_1.setObjectName(_fromUtf8("input_1"))
previewButton.clicked.connect(self.previewButton_clicked)
input_1.cursorPositionChanged.connect(input_1.selectAll)
self.setWindowTitle('Barcode Generator')
self.show()
def previewButton_clicked(self):
self.input_1.toPlainText()
sum = 0.0
if float(addend1) > 0:
sum = sum + addend1
strSum = str('%.3f' % sum)
print(strSum)
def main():
app = QtGui.QApplication(sys.argv)
Form = MyWindowClass()
sys.exit(app.exec_())
if __name__ == '__main__':
main()