Event fired twice using button box in Pyqt - python

This app is a basic Drag'n'Drop program and should handle dropped .html files.
So far I have written this code:
main.py
from PyQt4 import QtGui
import sys
import design, os
class MyTextEdit(QtGui.QTextEdit):
def __init__(self, parent):
super(MyTextEdit, self).__init__(parent)
self.setAcceptDrops(True)
self.list_of_dropped_files = []
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
event.ignore()
def dragMoveEvent(self, event):
event.accept()
def dropEvent(self, event):
self.clear()
self.list_of_dropped_files = event.mimeData().urls()
for single_file in self.list_of_dropped_files:
self.append(single_file.toLocalFile())
class DialogInit(QtGui.QDialog, design.Ui_Dialog):
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.buttonBox.accepted.connect(self.accept) # handle the ok button click
self.textEditHandler = MyTextEdit(self.textEdit)
def accept(self):
print self.textEditHandler.list_of_dropped_files
def main():
app = QtGui.QApplication(sys.argv)
form = DialogInit()
form.show()
app.exec_()
if __name__ == '__main__':
main()
and I created also a design.py code using the QtDesigner that looks like as follows:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
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_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName(_fromUtf8("Dialog"))
Dialog.resize(409, 80)
self.verticalLayoutWidget = QtGui.QWidget(Dialog)
self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 401, 71))
self.verticalLayoutWidget.setObjectName(_fromUtf8("verticalLayoutWidget"))
self.verticalLayout = QtGui.QVBoxLayout(self.verticalLayoutWidget)
self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))
self.horizontalLayout = QtGui.QHBoxLayout()
self.horizontalLayout.setObjectName(_fromUtf8("horizontalLayout"))
self.label = QtGui.QLabel(self.verticalLayoutWidget)
font = QtGui.QFont()
font.setPointSize(12)
self.label.setFont(font)
self.label.setObjectName(_fromUtf8("label"))
self.horizontalLayout.addWidget(self.label)
self.textEdit = QtGui.QTextEdit(self.verticalLayoutWidget)
self.textEdit.setAcceptDrops(True)
self.textEdit.setObjectName(_fromUtf8("textEdit"))
self.horizontalLayout.addWidget(self.textEdit)
self.verticalLayout.addLayout(self.horizontalLayout)
self.buttonBox = QtGui.QDialogButtonBox(self.verticalLayoutWidget)
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
self.verticalLayout.addWidget(self.buttonBox)
self.retranslateUi(Dialog)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("rejected()")), Dialog.reject)
QtCore.QObject.connect(self.buttonBox, QtCore.SIGNAL(_fromUtf8("accepted()")), Dialog.accept)
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(_translate("Dialog", "Dialog", None))
self.label.setText(_translate("Dialog", "Drop .html file(s):", None))
However, after the Ok button from the button box has been pressed, the event and therefore the function accept(), is fired twice.
Furthermore I found that after dropping several files into the QTextEdit, the widget doesn't change its height or at least a scroll pane is added automatically.
Any ideas how to fix the both issues?
I think also that my code is pretty messed up, it works, but it is not really well programmed.
Can someone please give an advice how to refactor the code? What could I have been better?
Thanks!

I've found myself a solution for closing the QDialog issue after the ok button has been clicked. I had to remove the accept() slot in the design.py.
However, I still can't see a scrollbar added when several files have been droppped.

Related

show arrows in QStackedWidget [duplicate]

I have two buttons (wgtbtnA & wgtbtnB) placed on two different pages (page1 and page2, respectively) inside a parent object (objectName: stackedWidget). My dilemma is this: when I run the code, the arrows don't display in PyQt. Why? How do I alternate from page1 to page2 and vice-versa?
Here is an image of runtime, which conveys what I am asking for:
Qt Designer:
I'd like to keep those small back arrows.
Below is my code:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'stackedWidget.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
import sys
import os
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(512, 304)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.stackedWidget = QtGui.QStackedWidget(self.centralwidget)
self.stackedWidget.setGeometry(QtCore.QRect(150, 60, 161, 121))
self.stackedWidget.setObjectName(_fromUtf8("stackedWidget"))
self.page = QtGui.QWidget()
self.page.setObjectName(_fromUtf8("page"))
self.wgtMainWindow = QtGui.QPushButton(self.page)
self.wgtMainWindow.setGeometry(QtCore.QRect(50, 50, 75, 23))
self.wgtMainWindow.setObjectName(_fromUtf8("wgtMainWindow"))
self.stackedWidget.addWidget(self.page)
self.page_2 = QtGui.QWidget()
self.page_2.setObjectName(_fromUtf8("page_2"))
self.wgtbtnB = QtGui.QPushButton(self.page_2)
self.wgtbtnB.setGeometry(QtCore.QRect(50, 50, 75, 23))
self.wgtbtnB.setObjectName(_fromUtf8("wgtbtnB"))
self.stackedWidget.addWidget(self.page_2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 512, 21))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.stackedWidget.setCurrentIndex(1)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.wgtMainWindow.setText(_translate("MainWindow", "Widget A", None))
self.wgtbtnB.setText(_translate("MainWindow", "Widget B", None))
class ControlMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(ControlMainWindow, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mySW = ControlMainWindow()
mySW.show()
sys.exit(app.exec_())
You could use the buttons to change the page: {your QPushButton}.clicked.connect(lambda: {your QStackedWidget}.setCurrentIndex({another page}))
By Example:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'stackedWidget.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
import sys
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(512, 304)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.stackedWidget = QtGui.QStackedWidget(self.centralwidget)
self.stackedWidget.setGeometry(QtCore.QRect(150, 60, 161, 121))
self.stackedWidget.setObjectName(_fromUtf8("stackedWidget"))
self.page = QtGui.QWidget()
self.page.setObjectName(_fromUtf8("page"))
self.wgtMainWindow = QtGui.QPushButton(self.page)
self.wgtMainWindow.setGeometry(QtCore.QRect(50, 50, 75, 23))
self.wgtMainWindow.setObjectName(_fromUtf8("wgtMainWindow"))
self.stackedWidget.addWidget(self.page)
self.page_2 = QtGui.QWidget()
self.page_2.setObjectName(_fromUtf8("page_2"))
self.wgtbtnB = QtGui.QPushButton(self.page_2)
self.wgtbtnB.setGeometry(QtCore.QRect(50, 50, 75, 23))
self.wgtbtnB.setObjectName(_fromUtf8("wgtbtnB"))
self.stackedWidget.addWidget(self.page_2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 512, 21))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.stackedWidget.setCurrentIndex(1)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.wgtMainWindow.setText(_translate("MainWindow", "Widget A", None))
self.wgtbtnB.setText(_translate("MainWindow", "Widget B", None))
class ControlMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(ControlMainWindow, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.wgtbtnB.clicked.connect(lambda : self.ui.stackedWidget.setCurrentIndex(0))
self.ui.wgtMainWindow.clicked.connect(lambda : self.ui.stackedWidget.setCurrentIndex(1))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mySW = ControlMainWindow()
mySW.show()
sys.exit(app.exec_())
Start app:
after clicked button:
after clicked another button:
the two arrows you see in the designer ( in your message below) don't carry over to your application, its a function in the designer so you can switch between them easily
To implement your arrows from one screen to the next you just need to propagate those arrows making sure that they appear in each view -- now this can easily be done via code cannot say how difficult it might be in the designer. Here is a example that does something like what you might be wanting.
from sys import exit as sysExit
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Win1Disply(QFrame):
def __init__(self, parent):
QFrame.__init__(self)
self.setFrameShape(QFrame.StyledPanel)
self.setLineWidth(0.2)
# -------
self.Cntnr = QVBoxLayout()
self.Cntnr.addWidget(QTextEdit('This is Window 1 with whatever contents you want'))
self.Win1Btn = QPushButton('>>')
self.Win1Btn.clicked.connect(parent.RightArrow)
self.Cntnr.addWidget(self.Win1Btn)
self.Cntnr.addStretch(1)
# -------
self.setLayout(self.Cntnr)
class Win2Disply(QFrame):
def __init__(self, parent):
QFrame.__init__(self)
self.setFrameShape(QFrame.StyledPanel)
self.setLineWidth(0.2)
# -------
self.Cntnr = QVBoxLayout()
self.Cntnr.addWidget(QTextEdit('This is Window 2 with whatever contents you want'))
self.Win1Btn = QPushButton('>>')
self.Win1Btn.clicked.connect(parent.RightArrow)
self.Cntnr.addWidget(self.Win1Btn)
self.Cntnr.addStretch(1)
# -------
self.setLayout(self.Cntnr)
class OptionButtons(QToolButton):
# Class OptionButtons ("Text", Connector) inherits from QToolButton
def __init__(self, Text, Connector):
QToolButton.__init__(self)
self.setText(Text)
self.setStyleSheet("font: bold;color: blue;height: 55px;width: 55px;")
self.setIconSize(QSize(32,32))
self.clicked.connect(Connector)
############################## Settings Class ##############################
class OptionSettings(QDialog):
def __init__(self, parent):
QDialog.__init__(self, parent)
line = QFrame()
line.setFrameShape(QFrame.HLine)
line.setFrameShadow(QFrame.Sunken)
self.btnWin1 = OptionButtons('Win One', self.ShowWindow1)
self.btnWin2 = OptionButtons('Win Two', self.ShowWindow2)
# Vertical Box for Buttons *************************************
self.UpLeft = QVBoxLayout()
self.UpLeft.addWidget(self.btnWin1)
self.UpLeft.addWidget(self.btnWin2)
self.UpLeft.addStretch(1)
# Display Area on Right
# Widget Flip Display ******************************************
self.UpRite = QHBoxLayout()
self.Contents = QStackedWidget()
self.Contents.addWidget(QTextEdit('Nothing Selected'))
self.Contents.addWidget(Win1Disply(self))
self.Contents.addWidget(Win2Disply(self))
self.Contents.addWidget(QTextEdit('Settings Saved'))
self.Contents.setCurrentIndex(0)
self.UpRite.addWidget(self.Contents)
# Button and Display Area on Top
self.Upper = QHBoxLayout()
self.Upper.addLayout(self.UpLeft)
self.Upper.addLayout(self.UpRite)
# Save and Cancel Area on Bottom
self.btnSave = QPushButton("Save")
self.btnSave.clicked.connect(self.SaveSettings)
self.btnCncl = QPushButton("Cancel")
self.btnCncl.clicked.connect(self.close)
self.Lower = QHBoxLayout()
self.Lower.addStretch(1)
self.Lower.addWidget(self.btnSave)
self.Lower.addWidget(self.btnCncl)
# Entire Options Window Layout
self.OuterBox = QVBoxLayout()
self.OuterBox.addLayout(self.Upper)
self.OuterBox.addLayout(self.Lower)
self.setLayout(self.OuterBox)
self.setWindowTitle('Settings')
#Geometry(Left, Top, Width, Hight)
self.setGeometry(250, 250, 550, 450)
self.setModal(True)
self.exec()
def ShowWindow1(self):
self.Contents.setCurrentIndex(1)
def ShowWindow2(self):
self.Contents.setCurrentIndex(2)
def SaveSettings(self):
self.Contents.setCurrentIndex(3)
def RightArrow(self):
if self.Contents.currentIndex() == 1:
self.Contents.setCurrentIndex(2)
else:
self.Contents.setCurrentIndex(1)
class CenterPanel(QWidget):
def __init__(self, MainWin):
QWidget.__init__(self)
CntrPane = QTextEdit('Center Panel is Placed Here')
hbox = QHBoxLayout(self)
hbox.addWidget(CntrPane)
self.setLayout(hbox)
class MenuToolBar(QDockWidget):
def __init__(self, MainWin):
QDockWidget.__init__(self)
self.MainWin = MainWin
self.MainMenu = MainWin.menuBar()
self.WndowMenu = self.MainMenu.addMenu('Windows')
self.OptnAct = QAction('Options', self)
self.OptnAct.setStatusTip('Open the Options Window')
self.OptnAct.triggered.connect(MainWin.ShowOptions)
self.WndowMenu.addAction(self.OptnAct)
self.InitToolBar(MainWin)
def InitToolBar(self, MainWin):
self.mainToolBar = MainWin.addToolBar("Quick Access")
self.mainToolBar.addAction(self.OptnAct)
class UI_MainWindow(QMainWindow):
def __init__(self):
super(UI_MainWindow, self).__init__()
self.setWindowTitle('Main Window')
# Left, Top, Width, Height
self.setGeometry(200, 200, 550, 550)
self.CenterPane = CenterPanel(self)
self.setCentralWidget(self.CenterPane)
self.MenuToolBar = MenuToolBar(self)
def ShowOptions(self):
self.Options = OptionSettings(self)
if __name__ == '__main__':
MainApp = QApplication([])
MainGui = UI_MainWindow()
MainGui.show()
sysExit(MainApp.exec_())
If you really need arrows in your stacked widget, another solution is to implement your own "Promoted Widget": it allows you to create your design with custom widgets, that might extend the basic widgets provided by Qt. You won't be able to interact with your own implementation in Designer, but you'll get the result once you run your program.
This is the procedure: create your own subclass of the widget you want to extend, define your custom methods or override existing ones (remember that some private methods require a specific return value type, check the documentation).
It's usually better to save the subclass(es) you created in a separate files.
Then, in Designer add the widget you need (in this case, StackedWidget), right click on it and select "Promote to..."; in the dialog that will be shown, type the subclass name you created in the "Promoted class name" field (in the example below, it will be "StackedWidgetWithArrowButtons") and the file that contains it in the "header file" field: it will be treated as a python import, so do not add the trailing ".py" and remember that if you saved it in a subdirectory you'll need the full "module" path, for example "mysubclasses.customstackwidget", if the file is "customstackwidget" in the "mysubclasses" directory.
Save the ui, compile it and run the program.
class StackedWidgetWithArrowButtons(QtWidgets.QStackedWidget):
def __init__(self, *args, **kwargs):
QtWidgets.QStackedWidget.__init__(self, *args, **kwargs)
self.backwardButton = QtWidgets.QToolButton(self)
self.backwardButton.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowLeft))
self.backwardButton.setMaximumSize(24, 24)
self.backwardButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.forwardButton = QtWidgets.QToolButton(self)
self.forwardButton.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowRight))
self.forwardButton.setMaximumSize(24, 24)
self.forwardButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.currentChanged.connect(self.checkSwitchButtons)
def checkSwitchButtons(self):
self.forwardButton.setEnabled(self.currentIndex() < self.count() - 1)
self.backwardButton.setEnabled(self.currentIndex() > 0)
def addWidget(self, widget):
# this is a private method of QStackedWidget that is called when
# the ui is being built by the program, we just implement it
# to ensure that the buttons are correctly enabled;
# the index *has* to be returned
index = QtWidgets.QStackedWidget.addWidget(self, widget)
self.checkSwitchButtons()
return index
def removeWidget(self, widget):
# not necessary, but in case you want to remove widgets in the
# future, it will check buttons again
index = QtWidgets.QStackedWidget.removeWidget(self, widget)
self.checkSwitchButtons()
return index
def mousePressEvent(self, event):
# due to the way QStackedWidget is implemented, children widgets
# that are not in its layout might not receive mouse events,
# but we just need to track clicks so this is enough
if event.button() == QtCore.Qt.LeftButton:
if event.pos() in self.backwardButton.geometry():
self.setCurrentIndex(self.currentIndex() - 1)
elif event.pos() in self.forwardButton.geometry():
self.setCurrentIndex(self.currentIndex() + 1)
def resizeEvent(self, event):
# the base class resizeEvent *has* to be called, otherwise
# you could encounter problems with children widgets
QtWidgets.QStackedWidget.resizeEvent(self, event)
# now ensure that the buttons are always placed on the top
# right corner; this positioning is completely manual and you
# have to take button sizes in consideration to avoid
# overlapping buttons; obviously you can place them wherever
# you want.
self.forwardButton.move(self.rect().right() - self.forwardButton.width(), 0)
self.backwardButton.move(self.forwardButton.x() - self.backwardButton.width(), 0)
If you don't want buttons (or you don't like the way they appear) you could implement your own paintEvent. In this case I created small triangles using QPolygons.
class StackedWidgetWithTriangles(QtWidgets.QStackedWidget):
def __init__(self, *args, **kwargs):
QtWidgets.QStackedWidget.__init__(self, *args, **kwargs)
self.backwardRect = QtCore.QRect(0, 0, 16, 16)
self.forwardRect = QtCore.QRect(0, 0, 16, 16)
self.forwardArrow = QtGui.QPolygon([QtCore.QPoint(-6, -6), QtCore.QPoint(6, 0), QtCore.QPoint(-6, 6)])
self.backwardArrow = QtGui.QPolygon([QtCore.QPoint(6, -6), QtCore.QPoint(-6, 0), QtCore.QPoint(6, 6)])
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
if event.pos() in self.backwardRect:
self.setCurrentIndex(self.currentIndex() - 1)
elif event.pos() in self.forwardRect:
self.setCurrentIndex(self.currentIndex() + 1)
def resizeEvent(self, event):
QtWidgets.QStackedWidget.resizeEvent(self, event)
self.forwardRect.moveLeft(self.rect().right() - self.forwardRect.width())
self.backwardRect.moveLeft(self.forwardRect.x() - self.forwardRect.width())
def paintEvent(self, event):
qp = QtGui.QPainter(self)
qp.setRenderHints(qp.Antialiasing)
# set colors according to the possibility of going back or forward,
# showing a "disabled" arrow whenever it's not possible
if self.currentIndex() > 0:
qp.setPen(QtCore.Qt.darkGray)
qp.setBrush(QtCore.Qt.black)
else:
qp.setPen(QtCore.Qt.lightGray)
qp.setBrush(QtCore.Qt.transparent)
qp.drawPolygon(self.backwardArrow.translated(self.backwardRect.center()))
if self.currentIndex() < self.count() - 1:
qp.setPen(QtCore.Qt.darkGray)
qp.setBrush(QtCore.Qt.black)
else:
qp.setPen(QtCore.Qt.lightGray)
qp.setBrush(QtCore.Qt.transparent)
qp.drawPolygon(self.forwardArrow.translated(self.forwardRect.center()))
you have no logic in your ControlMainWindow class to switch between your widgets. (also i don't see any arrow widgets for switching) you'll need to add a listener to your QTbuttons in your main class like below to execute your logic:
yourQTbutton.itemClicked.connect(self.functioWithUIchangingLogic)

PyQt: How to switch widgets in QStackedWidget

I have two buttons (wgtbtnA & wgtbtnB) placed on two different pages (page1 and page2, respectively) inside a parent object (objectName: stackedWidget). My dilemma is this: when I run the code, the arrows don't display in PyQt. Why? How do I alternate from page1 to page2 and vice-versa?
Here is an image of runtime, which conveys what I am asking for:
Qt Designer:
I'd like to keep those small back arrows.
Below is my code:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'stackedWidget.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
import sys
import os
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(512, 304)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.stackedWidget = QtGui.QStackedWidget(self.centralwidget)
self.stackedWidget.setGeometry(QtCore.QRect(150, 60, 161, 121))
self.stackedWidget.setObjectName(_fromUtf8("stackedWidget"))
self.page = QtGui.QWidget()
self.page.setObjectName(_fromUtf8("page"))
self.wgtMainWindow = QtGui.QPushButton(self.page)
self.wgtMainWindow.setGeometry(QtCore.QRect(50, 50, 75, 23))
self.wgtMainWindow.setObjectName(_fromUtf8("wgtMainWindow"))
self.stackedWidget.addWidget(self.page)
self.page_2 = QtGui.QWidget()
self.page_2.setObjectName(_fromUtf8("page_2"))
self.wgtbtnB = QtGui.QPushButton(self.page_2)
self.wgtbtnB.setGeometry(QtCore.QRect(50, 50, 75, 23))
self.wgtbtnB.setObjectName(_fromUtf8("wgtbtnB"))
self.stackedWidget.addWidget(self.page_2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 512, 21))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.stackedWidget.setCurrentIndex(1)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.wgtMainWindow.setText(_translate("MainWindow", "Widget A", None))
self.wgtbtnB.setText(_translate("MainWindow", "Widget B", None))
class ControlMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(ControlMainWindow, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mySW = ControlMainWindow()
mySW.show()
sys.exit(app.exec_())
You could use the buttons to change the page: {your QPushButton}.clicked.connect(lambda: {your QStackedWidget}.setCurrentIndex({another page}))
By Example:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'stackedWidget.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!
from PyQt4 import QtCore, QtGui
import sys
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(512, 304)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.stackedWidget = QtGui.QStackedWidget(self.centralwidget)
self.stackedWidget.setGeometry(QtCore.QRect(150, 60, 161, 121))
self.stackedWidget.setObjectName(_fromUtf8("stackedWidget"))
self.page = QtGui.QWidget()
self.page.setObjectName(_fromUtf8("page"))
self.wgtMainWindow = QtGui.QPushButton(self.page)
self.wgtMainWindow.setGeometry(QtCore.QRect(50, 50, 75, 23))
self.wgtMainWindow.setObjectName(_fromUtf8("wgtMainWindow"))
self.stackedWidget.addWidget(self.page)
self.page_2 = QtGui.QWidget()
self.page_2.setObjectName(_fromUtf8("page_2"))
self.wgtbtnB = QtGui.QPushButton(self.page_2)
self.wgtbtnB.setGeometry(QtCore.QRect(50, 50, 75, 23))
self.wgtbtnB.setObjectName(_fromUtf8("wgtbtnB"))
self.stackedWidget.addWidget(self.page_2)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 512, 21))
self.menubar.setObjectName(_fromUtf8("menubar"))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.stackedWidget.setCurrentIndex(1)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.wgtMainWindow.setText(_translate("MainWindow", "Widget A", None))
self.wgtbtnB.setText(_translate("MainWindow", "Widget B", None))
class ControlMainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(ControlMainWindow, self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.ui.wgtbtnB.clicked.connect(lambda : self.ui.stackedWidget.setCurrentIndex(0))
self.ui.wgtMainWindow.clicked.connect(lambda : self.ui.stackedWidget.setCurrentIndex(1))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
mySW = ControlMainWindow()
mySW.show()
sys.exit(app.exec_())
Start app:
after clicked button:
after clicked another button:
the two arrows you see in the designer ( in your message below) don't carry over to your application, its a function in the designer so you can switch between them easily
To implement your arrows from one screen to the next you just need to propagate those arrows making sure that they appear in each view -- now this can easily be done via code cannot say how difficult it might be in the designer. Here is a example that does something like what you might be wanting.
from sys import exit as sysExit
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
class Win1Disply(QFrame):
def __init__(self, parent):
QFrame.__init__(self)
self.setFrameShape(QFrame.StyledPanel)
self.setLineWidth(0.2)
# -------
self.Cntnr = QVBoxLayout()
self.Cntnr.addWidget(QTextEdit('This is Window 1 with whatever contents you want'))
self.Win1Btn = QPushButton('>>')
self.Win1Btn.clicked.connect(parent.RightArrow)
self.Cntnr.addWidget(self.Win1Btn)
self.Cntnr.addStretch(1)
# -------
self.setLayout(self.Cntnr)
class Win2Disply(QFrame):
def __init__(self, parent):
QFrame.__init__(self)
self.setFrameShape(QFrame.StyledPanel)
self.setLineWidth(0.2)
# -------
self.Cntnr = QVBoxLayout()
self.Cntnr.addWidget(QTextEdit('This is Window 2 with whatever contents you want'))
self.Win1Btn = QPushButton('>>')
self.Win1Btn.clicked.connect(parent.RightArrow)
self.Cntnr.addWidget(self.Win1Btn)
self.Cntnr.addStretch(1)
# -------
self.setLayout(self.Cntnr)
class OptionButtons(QToolButton):
# Class OptionButtons ("Text", Connector) inherits from QToolButton
def __init__(self, Text, Connector):
QToolButton.__init__(self)
self.setText(Text)
self.setStyleSheet("font: bold;color: blue;height: 55px;width: 55px;")
self.setIconSize(QSize(32,32))
self.clicked.connect(Connector)
############################## Settings Class ##############################
class OptionSettings(QDialog):
def __init__(self, parent):
QDialog.__init__(self, parent)
line = QFrame()
line.setFrameShape(QFrame.HLine)
line.setFrameShadow(QFrame.Sunken)
self.btnWin1 = OptionButtons('Win One', self.ShowWindow1)
self.btnWin2 = OptionButtons('Win Two', self.ShowWindow2)
# Vertical Box for Buttons *************************************
self.UpLeft = QVBoxLayout()
self.UpLeft.addWidget(self.btnWin1)
self.UpLeft.addWidget(self.btnWin2)
self.UpLeft.addStretch(1)
# Display Area on Right
# Widget Flip Display ******************************************
self.UpRite = QHBoxLayout()
self.Contents = QStackedWidget()
self.Contents.addWidget(QTextEdit('Nothing Selected'))
self.Contents.addWidget(Win1Disply(self))
self.Contents.addWidget(Win2Disply(self))
self.Contents.addWidget(QTextEdit('Settings Saved'))
self.Contents.setCurrentIndex(0)
self.UpRite.addWidget(self.Contents)
# Button and Display Area on Top
self.Upper = QHBoxLayout()
self.Upper.addLayout(self.UpLeft)
self.Upper.addLayout(self.UpRite)
# Save and Cancel Area on Bottom
self.btnSave = QPushButton("Save")
self.btnSave.clicked.connect(self.SaveSettings)
self.btnCncl = QPushButton("Cancel")
self.btnCncl.clicked.connect(self.close)
self.Lower = QHBoxLayout()
self.Lower.addStretch(1)
self.Lower.addWidget(self.btnSave)
self.Lower.addWidget(self.btnCncl)
# Entire Options Window Layout
self.OuterBox = QVBoxLayout()
self.OuterBox.addLayout(self.Upper)
self.OuterBox.addLayout(self.Lower)
self.setLayout(self.OuterBox)
self.setWindowTitle('Settings')
#Geometry(Left, Top, Width, Hight)
self.setGeometry(250, 250, 550, 450)
self.setModal(True)
self.exec()
def ShowWindow1(self):
self.Contents.setCurrentIndex(1)
def ShowWindow2(self):
self.Contents.setCurrentIndex(2)
def SaveSettings(self):
self.Contents.setCurrentIndex(3)
def RightArrow(self):
if self.Contents.currentIndex() == 1:
self.Contents.setCurrentIndex(2)
else:
self.Contents.setCurrentIndex(1)
class CenterPanel(QWidget):
def __init__(self, MainWin):
QWidget.__init__(self)
CntrPane = QTextEdit('Center Panel is Placed Here')
hbox = QHBoxLayout(self)
hbox.addWidget(CntrPane)
self.setLayout(hbox)
class MenuToolBar(QDockWidget):
def __init__(self, MainWin):
QDockWidget.__init__(self)
self.MainWin = MainWin
self.MainMenu = MainWin.menuBar()
self.WndowMenu = self.MainMenu.addMenu('Windows')
self.OptnAct = QAction('Options', self)
self.OptnAct.setStatusTip('Open the Options Window')
self.OptnAct.triggered.connect(MainWin.ShowOptions)
self.WndowMenu.addAction(self.OptnAct)
self.InitToolBar(MainWin)
def InitToolBar(self, MainWin):
self.mainToolBar = MainWin.addToolBar("Quick Access")
self.mainToolBar.addAction(self.OptnAct)
class UI_MainWindow(QMainWindow):
def __init__(self):
super(UI_MainWindow, self).__init__()
self.setWindowTitle('Main Window')
# Left, Top, Width, Height
self.setGeometry(200, 200, 550, 550)
self.CenterPane = CenterPanel(self)
self.setCentralWidget(self.CenterPane)
self.MenuToolBar = MenuToolBar(self)
def ShowOptions(self):
self.Options = OptionSettings(self)
if __name__ == '__main__':
MainApp = QApplication([])
MainGui = UI_MainWindow()
MainGui.show()
sysExit(MainApp.exec_())
If you really need arrows in your stacked widget, another solution is to implement your own "Promoted Widget": it allows you to create your design with custom widgets, that might extend the basic widgets provided by Qt. You won't be able to interact with your own implementation in Designer, but you'll get the result once you run your program.
This is the procedure: create your own subclass of the widget you want to extend, define your custom methods or override existing ones (remember that some private methods require a specific return value type, check the documentation).
It's usually better to save the subclass(es) you created in a separate files.
Then, in Designer add the widget you need (in this case, StackedWidget), right click on it and select "Promote to..."; in the dialog that will be shown, type the subclass name you created in the "Promoted class name" field (in the example below, it will be "StackedWidgetWithArrowButtons") and the file that contains it in the "header file" field: it will be treated as a python import, so do not add the trailing ".py" and remember that if you saved it in a subdirectory you'll need the full "module" path, for example "mysubclasses.customstackwidget", if the file is "customstackwidget" in the "mysubclasses" directory.
Save the ui, compile it and run the program.
class StackedWidgetWithArrowButtons(QtWidgets.QStackedWidget):
def __init__(self, *args, **kwargs):
QtWidgets.QStackedWidget.__init__(self, *args, **kwargs)
self.backwardButton = QtWidgets.QToolButton(self)
self.backwardButton.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowLeft))
self.backwardButton.setMaximumSize(24, 24)
self.backwardButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.forwardButton = QtWidgets.QToolButton(self)
self.forwardButton.setIcon(self.style().standardIcon(QtWidgets.QStyle.SP_ArrowRight))
self.forwardButton.setMaximumSize(24, 24)
self.forwardButton.setFocusPolicy(QtCore.Qt.NoFocus)
self.currentChanged.connect(self.checkSwitchButtons)
def checkSwitchButtons(self):
self.forwardButton.setEnabled(self.currentIndex() < self.count() - 1)
self.backwardButton.setEnabled(self.currentIndex() > 0)
def addWidget(self, widget):
# this is a private method of QStackedWidget that is called when
# the ui is being built by the program, we just implement it
# to ensure that the buttons are correctly enabled;
# the index *has* to be returned
index = QtWidgets.QStackedWidget.addWidget(self, widget)
self.checkSwitchButtons()
return index
def removeWidget(self, widget):
# not necessary, but in case you want to remove widgets in the
# future, it will check buttons again
index = QtWidgets.QStackedWidget.removeWidget(self, widget)
self.checkSwitchButtons()
return index
def mousePressEvent(self, event):
# due to the way QStackedWidget is implemented, children widgets
# that are not in its layout might not receive mouse events,
# but we just need to track clicks so this is enough
if event.button() == QtCore.Qt.LeftButton:
if event.pos() in self.backwardButton.geometry():
self.setCurrentIndex(self.currentIndex() - 1)
elif event.pos() in self.forwardButton.geometry():
self.setCurrentIndex(self.currentIndex() + 1)
def resizeEvent(self, event):
# the base class resizeEvent *has* to be called, otherwise
# you could encounter problems with children widgets
QtWidgets.QStackedWidget.resizeEvent(self, event)
# now ensure that the buttons are always placed on the top
# right corner; this positioning is completely manual and you
# have to take button sizes in consideration to avoid
# overlapping buttons; obviously you can place them wherever
# you want.
self.forwardButton.move(self.rect().right() - self.forwardButton.width(), 0)
self.backwardButton.move(self.forwardButton.x() - self.backwardButton.width(), 0)
If you don't want buttons (or you don't like the way they appear) you could implement your own paintEvent. In this case I created small triangles using QPolygons.
class StackedWidgetWithTriangles(QtWidgets.QStackedWidget):
def __init__(self, *args, **kwargs):
QtWidgets.QStackedWidget.__init__(self, *args, **kwargs)
self.backwardRect = QtCore.QRect(0, 0, 16, 16)
self.forwardRect = QtCore.QRect(0, 0, 16, 16)
self.forwardArrow = QtGui.QPolygon([QtCore.QPoint(-6, -6), QtCore.QPoint(6, 0), QtCore.QPoint(-6, 6)])
self.backwardArrow = QtGui.QPolygon([QtCore.QPoint(6, -6), QtCore.QPoint(-6, 0), QtCore.QPoint(6, 6)])
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
if event.pos() in self.backwardRect:
self.setCurrentIndex(self.currentIndex() - 1)
elif event.pos() in self.forwardRect:
self.setCurrentIndex(self.currentIndex() + 1)
def resizeEvent(self, event):
QtWidgets.QStackedWidget.resizeEvent(self, event)
self.forwardRect.moveLeft(self.rect().right() - self.forwardRect.width())
self.backwardRect.moveLeft(self.forwardRect.x() - self.forwardRect.width())
def paintEvent(self, event):
qp = QtGui.QPainter(self)
qp.setRenderHints(qp.Antialiasing)
# set colors according to the possibility of going back or forward,
# showing a "disabled" arrow whenever it's not possible
if self.currentIndex() > 0:
qp.setPen(QtCore.Qt.darkGray)
qp.setBrush(QtCore.Qt.black)
else:
qp.setPen(QtCore.Qt.lightGray)
qp.setBrush(QtCore.Qt.transparent)
qp.drawPolygon(self.backwardArrow.translated(self.backwardRect.center()))
if self.currentIndex() < self.count() - 1:
qp.setPen(QtCore.Qt.darkGray)
qp.setBrush(QtCore.Qt.black)
else:
qp.setPen(QtCore.Qt.lightGray)
qp.setBrush(QtCore.Qt.transparent)
qp.drawPolygon(self.forwardArrow.translated(self.forwardRect.center()))
you have no logic in your ControlMainWindow class to switch between your widgets. (also i don't see any arrow widgets for switching) you'll need to add a listener to your QTbuttons in your main class like below to execute your logic:
yourQTbutton.itemClicked.connect(self.functioWithUIchangingLogic)

Python & PyQt: Catch Minimize Event

Uhhh... Can somebody please help me with this? I can't seem to catch the minimize event of a widget I created. I tried solutions from every post I could find but it just doesn't seem to work with my code. In one of the solutions I tried, the window minimized and the system tray icon shows up but the app icon is still visible on the taskbar. I can't seem to figure out what I should be doing or what I'm missing here. I'm using Python 2.7 and PyQt 4.11. My OS is Windows 7 so I'm pretty sure its not an os issue. I'd really appreciate it if someone could help me here.
Here is the code.
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import *
from PyQt4.QtCore import *
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_Form(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.setupUi(self)
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(385, 277)
self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.radioButton = QtGui.QRadioButton(Form)
self.radioButton.setObjectName(_fromUtf8("radioButton"))
self.gridLayout.addWidget(self.radioButton, 0, 1, 1, 1)
self.lineEdit = QtGui.QLineEdit(Form)
self.lineEdit.setObjectName(_fromUtf8("lineEdit"))
self.gridLayout.addWidget(self.lineEdit, 1, 0, 1, 1)
self.pushButton = QtGui.QPushButton(Form)
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.gridLayout.addWidget(self.pushButton, 1, 1, 1, 1)
self.listWidget = QtGui.QListWidget(Form)
self.listWidget.setEditTriggers(QtGui.QAbstractItemView.DoubleClicked|QtGui.QAbstractItemView.EditKeyPressed|QtGui.QAbstractItemView.SelectedClicked)
self.listWidget.setSelectionBehavior(QtGui.QAbstractItemView.SelectItems)
self.listWidget.setMovement(QtGui.QListView.Snap)
self.listWidget.setUniformItemSizes(False)
self.listWidget.setObjectName(_fromUtf8("listView"))
self.gridLayout.addWidget(self.listWidget, 2, 0, 1, 2)
#system tray
self.systemTrayIcon = QtGui.QSystemTrayIcon()
self.systemTrayIcon.setIcon(QtGui.QIcon(":/images/images/mad-icon.jpg"))
self.systemTrayIcon.setVisible(True)
self.systemTrayIcon.activated.connect(self.sysTrayIconActivated)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
Form.setWindowTitle(_translate("Form", "Form", None))
self.radioButton.setText(_translate("Form", "monitor clipboard", None))
self.pushButton.setText(_translate("Form", "Add", None))
#when system tray icon is clicked, if window is visible, then hide. if it is not visible, then show
def sysTrayIconActivated(self, reason):
if reason == QtGui.QSystemTrayIcon.Trigger:
if Form.isHidden():
Form.show()
else:
Form.hide()
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QWidget()
ui = Ui_Form()
ui.setupUi(Form)
Form.show()
sys.exit(app.exec_())
This code should work
def changeEvent(self, event):
if event.type() == QEvent.WindowStateChange:
if event.oldState() and Qt.WindowMinimized:
print("WindowMinimized")
elif event.oldState() == Qt.WindowNoState or self.windowState() == Qt.WindowMaximized:
print("WindowMaximized")
You could use the changeEvent provided by QWidget:
def changeEvent(self, event):
if event.type() == QEvent.WindowStateChange:
if self.windowState() & Qt.WindowMinimized:
pass

Save the selections made in the qcombobox in pyqt

I'm new to Pyqt programming. i tried to build a simple GUI which looks like the one in the picture:
This is the code which i wrote:
from PyQt4 import QtCore, QtGui
import subprocess
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_Dialog(object):
Ui_Dialog.hypermesh =0
def setupUi(self, Dialog):
Dialog.setObjectName(_fromUtf8("Dialog"))
Dialog.resize(435, 181)
self.gridLayout_2 = QtGui.QGridLayout(Dialog)
self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
self.groupBox = QtGui.QGroupBox(Dialog)
self.groupBox.setObjectName(_fromUtf8("groupBox"))
self.gridLayout = QtGui.QGridLayout(self.groupBox)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.pushButton = QtGui.QPushButton(self.groupBox)
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.gridLayout.addWidget(self.pushButton, 0, 0, 1, 1)
self.comboBox = QtGui.QComboBox(self.groupBox)
self.comboBox.setObjectName(_fromUtf8("comboBox"))
self.gridLayout.addWidget(self.comboBox, 0, 1, 1, 1)
self.pushButton_3 = QtGui.QPushButton(self.groupBox)
self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
self.gridLayout.addWidget(self.pushButton_3, 1, 0, 1, 1)
self.pushButton_2 = QtGui.QPushButton(self.groupBox)
self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
self.gridLayout.addWidget(self.pushButton_2, 1, 1, 1, 1)
self.gridLayout_2.addWidget(self.groupBox, 0, 0, 1, 1)
hypmv=[]
cont=subprocess.Popen('ls /usr/local/bin/hm*',stdout=subprocess.PIPE,stdin=subprocess.PIPE,shell=True)
contents = cont.stdout.readlines()
for i in range(len(contents)):
temp=contents[i].strip()
temp=temp.split('/')
size=len(temp)
hypmv.append(temp[size-1])
self.comboBox.addItem(_fromUtf8(""))
self.comboBox.setItemText(i, _translate("Dialog", hypmv[i], None))
self.retranslateUi(Dialog)
QtCore.QObject.connect(self.pushButton_3, QtCore.SIGNAL(_fromUtf8("clicked()")), Dialog.reject)
QtCore.QMetaObject.connectSlotsByName(Dialog)
QtCore.QObject.connect(self.pushButton,QtCore.SIGNAL(_fromUtf8("clicked()")),self.hypm)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(_translate("Dialog", "Dialog", None))
self.groupBox.setTitle(_translate("Dialog", "Software Selector", None))
self.pushButton.setText(_translate("Dialog", "Hypermesh(Pre processor)", None))
self.pushButton_3.setText(_translate("Dialog", "Quit", None))
self.pushButton_2.setText(_translate("Dialog", "Save", None))
def hypm(self):
Ui_Dialog.hypermesh = unicode(self.comboBox.currentText())
subprocess.Popen(Ui_Dialog.hypermesh,shell=True)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Dialog = QtGui.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
In the code the combobox items are intialized when the gui intializes and when i hit the button should open the software version which was selected in the combobox currently. this function it's doing pretty good.
But now i want to save the selection made by the user so that every time he invokes the gui he shouldn't select again the version previously he used in the combobox.
so if he selects hm_11.0 for the first time it should be everytime "hm_11.0" until he changes it. How can i do this??
This is the class you want to be reading: http://pyqt.sourceforge.net/Docs/PyQt4/qsettings.html
There is like a small tutorial inside (ctrl+f Restoring the State of a GUI Application).
You will use setValue to store information with par keyToSetting/valueOfSetting and reading with value keyToSetting.
Example:
import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.readSettings()
self.setWindowTitle('Simple')
self.show()
def readSettings(self):
settings = QtCore.QSettings("AyaanTech", "SoftwareTest")
self.setGeometry(settings.value("geometry", QtCore.QRect(300, 300, 250, 150)).toRect());
def writeSettings(self):
settings = QtCore.QSettings("AyaanTech", "SoftwareTest")
settings.setValue("geometry", self.geometry());
def closeEvent(self, event):
quit_msg = "Do you want to save position and size?"
reply = QtGui.QMessageBox.question(self, 'Message',
quit_msg, QtGui.QMessageBox.Yes, QtGui.QMessageBox.No, QtGui.QMessageBox.Cancel)
if reply == QtGui.QMessageBox.Yes:
self.writeSettings()
event.accept()
elif reply == QtGui.QMessageBox.No:
event.accept()
else:
event.ignore()
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()

PyQT: LineEdit over QTextEdit

Okay, I really need help with this... I have a dockwidget, and in that dockwidget I have a textedit. Ok, all is fine so far, and here is the code for that:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'out/untitled.ui'
#
# Created: Mon Sep 16 19:33:15 2013
# by: PyQt4 UI code generator 4.10.2
#
# WARNING! All changes made in this file will be lost!
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(320, 240)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
MainWindow.setCentralWidget(self.centralwidget)
self.dockWidget = QtGui.QDockWidget(MainWindow)
self.dockWidget.setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
self.dockWidget.setObjectName(_fromUtf8("dockWidget"))
self.textEdit = QtGui.QTextEdit()
self.textEdit.setGeometry(QtCore.QRect(40, 10, 104, 71))
self.textEdit.setObjectName(_fromUtf8("textEdit"))
self.dockWidget.setWidget(self.textEdit)
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(8), self.dockWidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QMainWindow()
f = Ui_MainWindow()
f.setupUi(Form)
Form.show()
sys.exit(app.exec_())
Now, what I want to do is place a line edit at the bottom of the window (or dockwidget) that, overlaps the text area, doesn't move when the dockwidget is resized, and fills the whole dockwidget. I have tried this:
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'out/untitled.ui'
#
# Created: Mon Sep 16 19:33:15 2013
# by: PyQt4 UI code generator 4.10.2
#
# WARNING! All changes made in this file will be lost!
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(320, 240)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
MainWindow.setCentralWidget(self.centralwidget)
self.dockWidget = QtGui.QDockWidget(MainWindow)
self.dockWidget.setFeatures(QtGui.QDockWidget.NoDockWidgetFeatures)
self.dockWidget.setObjectName(_fromUtf8("dockWidget"))
self.textEdit = QtGui.QTextEdit()
self.textEdit.setGeometry(QtCore.QRect(40, 10, 104, 71))
self.textEdit.setObjectName(_fromUtf8("textEdit"))
self.dockWidget.setWidget(self.textEdit)
QtGui.QLineEdit(self.dockWidget) # Line edit
MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(8), self.dockWidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
Form = QtGui.QMainWindow()
f = Ui_MainWindow()
f.setupUi(Form)
Form.show()
sys.exit(app.exec_())
but it is not what I want. I REALLY need to get this working, so any help would be great. Thank you.
Here is an example of how to display a widget on top of another:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
#---------
# IMPORT
#---------
import sys
from PyQt4 import QtGui, QtCore
#---------
# DEFINE
#---------
class MyWindow(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
self.pushButtonInput = QtGui.QPushButton(self)
self.pushButtonInput.setText("Toggle the QLineEdit widget!")
self.pushButtonInput.clicked.connect(self.on_pushButtonInput_clicked)
self.textEditInput = QtGui.QTextEdit(self)
self.textEditInput.setText("This is a QTextEdit widget.")
self.textEditInput.installEventFilter(self)
self.lineEditInput = QtGui.QLineEdit(self)
self.lineEditInput.setText("This is a QLineEdit widget.")
self.lineEditInput.hide()
self.layoutVertical = QtGui.QVBoxLayout(self)
self.layoutVertical.addWidget(self.pushButtonInput)
self.layoutVertical.addWidget(self.textEditInput)
def eventFilter(self, obj, event):
if event.type() == QtCore.QEvent.Resize:
geometry = self.textEditInput.geometry()
self.lineEditInput.setGeometry(geometry)
return super(MyWindow, self).eventFilter(obj, event)
#QtCore.pyqtSlot()
def on_pushButtonInput_clicked(self):
if self.lineEditInput.isVisible():
self.lineEditInput.hide()
else:
self.lineEditInput.show()
#---------
# MAIN
#---------
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWindow')
main = MyWindow()
main.show()
sys.exit(app.exec_())

Categories

Resources