Get settings from child window in Pyside - python

I have a few questions.
How do i properly get settings from the child window when i press 'Print' button?
How do i close the Settings window and save/commit changes only when user presses 'OK' vs 'Cancel' which just closes the dialog and dismisses the changes.
Settings Window
import sys
from PySide import QtGui, QtCore
class SettingsWindow(QtGui.QDialog):
def __init__(self, parent=None):
super(SettingsWindow, self).__init__(parent)
self.resize(200, 150)
self.setWindowTitle('Settings')
self.initUI()
def initUI(self):
lb_max = QtGui.QLabel('Max')
self.ui_max = QtGui.QSpinBox()
self.ui_max.setValue(5)
lb_min = QtGui.QLabel('Min')
self.ui_min = QtGui.QSpinBox()
self.ui_min.setValue(10)
lb_count = QtGui.QLabel('Count')
self.ui_count = QtGui.QSpinBox()
self.ui_count.setValue(25)
self.buttons = QtGui.QDialogButtonBox();
self.buttons.setOrientation(QtCore.Qt.Horizontal)
self.buttons.setStandardButtons(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel)
self.buttons.layout().setDirection(QtGui.QBoxLayout.LeftToRight)
grid = QtGui.QGridLayout()
grid.setContentsMargins(10,10,10,10)
grid.addWidget(lb_max,0,0)
grid.addWidget(self.ui_max,0,1)
grid.addWidget(lb_min,1,0)
grid.addWidget(self.ui_min,1,1)
grid.addWidget(lb_count,2,0)
grid.addWidget(self.ui_count,2,1)
grid.addWidget(self.buttons,3,1)
self.setLayout(grid)
Main Window
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.resize(200, 150)
self.setWindowTitle('Assets')
self.initUI()
def initUI(self):
self.mi_settings = QtGui.QAction('Settings', self)
self.mi_settings.triggered.connect(self.open_settings)
self.ui_button = QtGui.QPushButton('Print')
self.ui_button.clicked.connect(self.clicked_button)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(self.mi_settings)
grid = QtGui.QVBoxLayout()
grid.setContentsMargins(10,10,10,10)
grid.addWidget(self.ui_button)
main_widget = QtGui.QWidget()
main_widget.setLayout(grid)
self.setCentralWidget(main_widget)
def open_settings(self):
win = SettingsWindow()
win.exec_()
def clicked_button(self):
print 'Settings'
print '\tMax: '
print '\tMin: '
print '\tCount: '
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = MainWindow()
# ex = SettingsWindow()
ex.show()
sys.exit(app.exec_())

Firstly, you need to connect up the buttons in the dialog, so that you can tell whether the user cancelled it or not:
class SettingsWindow(QtGui.QDialog):
...
def initUI(self):
...
self.buttons = QtGui.QDialogButtonBox()
...
self.buttons.accepted.connect(self.accept)
self.buttons.rejected.connect(self.reject)
Secondly, you should think about how you set the defaults in the dialog, and how you reset/retrieve the current values. One way to do this would be to have a central settings dictionary where you store the values, with the dialog being used to update it from user input:
class SettingsWindow(QtGui.QDialog):
...
def getValues(self):
return {
'max': self.ui_max.value(),
'min': self.ui_min.value(),
'count': self.ui_count.value(),
}
def setValues(self, settings):
self.ui_max.setValue(settings['max'])
self.ui_min.setValue(settings['min'])
self.ui_count.setValue(settings['count'])
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
...
# default values
self.settings = {
'max': 5,
'min': 10,
'count': 25,
}
def open_settings(self):
win = SettingsWindow()
# reset from current values
win.setValues(self.settings)
if win.exec_() == QtGui.QDialog.Accepted:
# update only if user clicked ok
self.settings.update(win.getValues())
def clicked_button(self):
print 'Settings:'
for key in 'max', 'min', 'count':
print '\t%s = %s' % (key.title(), self.settings[key])
There are numerous ways to solve this kind of problem, but this should give you the general idea.

You can check the result of the exec_() command to see whether the dialog was accepted or rejected. If it was accepted, you can read the values of the GUI controls
win = SettingsWindow()
r = win.exec_()
if r:
min_val = win.ui_min.value()
max_val = win.ui_max.value()
cnt_val = win.ui_max.value()

Related

Python PyQt button click won't fire a event

i am new in PyQt but i have a problem i can't solve. I am trying to get text from second window and set it to field, so when i close second window i can print it form first main window, but my "AnotherWindow" button won't fire event and i really don't know why? Here is code. Can anyone guide me?
Thanks
class AnotherWindow(QMainWindow):
def __init__(self):
super().__init__()
self.resize(1200, 600)
self.text = "basetext"
self.layoutf = QFormLayout()
self.buttonf = QPushButton("get text")
self.buttonf.clicked.connect(lambda: self.getText)
self.line = QLineEdit()
self.layoutf.addRow(self.buttonf,self.line)
self.widgetf = QWidget()
self.widgetf.setLayout(self.layoutf)
self.setCentralWidget(self.widgetf)
def getText(self):
print(self.line.text)
self.text = self.line.text
self.close()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.w = None # No external window yet.
self.mainLayout = QGridLayout()
self.button = QPushButton("Push for Window")
self.button.clicked.connect(self.show_new_window)
self.button1 = QPushButton("Push ")
self.button1.clicked.connect(self.printFromSecondWindow)
self.mainLayout.addWidget(self.button,0,0)
self.mainLayout.addWidget(self.button1, 0, 1)
self.widget = QWidget()
self.widget.setLayout(self.mainLayout)
self.setCentralWidget(self.widget)
def show_new_window(self):
if self.w is None:
self.w = AnotherWindow()
self.w.show()
else:
self.w.close() # Close window.
self.w = None # Discard reference.
def printFromSecondWindow(self):
print(self.w.text)
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
The problem is with self.buttonf.clicked.connect(...). This call attaches a function to the "clicked" action on the button. The function is called without parameters and the return is simply discarded. In your case, lambda: self.get_text is a function that does nothing but return the address of the self.get_text method. Since get_text doesn't need any additional parameters, you can bind it directly to this slot.
self.buttonf.clicked.connect(self.get_text)
You also have a bug later on where you need to call the text method. With these two changes, the working program is
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.Qt import *
class AnotherWindow(QMainWindow):
def __init__(self):
super().__init__()
self.resize(1200, 600)
self.text = "basetext"
self.layoutf = QFormLayout()
self.buttonf = QPushButton("get text")
self.buttonf.clicked.connect(self.getText)
self.line = QLineEdit()
self.layoutf.addRow(self.buttonf,self.line)
self.widgetf = QWidget()
self.widgetf.setLayout(self.layoutf)
self.setCentralWidget(self.widgetf)
def getText(self):
print("the info", self.line.text())
self.text = self.line.text()
self.close()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.w = None # No external window yet.
self.mainLayout = QGridLayout()
self.button = QPushButton("Push for Window")
self.button.clicked.connect(self.show_new_window)
self.button1 = QPushButton("Push ")
self.button1.clicked.connect(self.printFromSecondWindow)
self.mainLayout.addWidget(self.button,0,0)
self.mainLayout.addWidget(self.button1, 0, 1)
self.widget = QWidget()
self.widget.setLayout(self.mainLayout)
self.setCentralWidget(self.widget)
def show_new_window(self):
if self.w is None:
self.w = AnotherWindow()
self.w.show()
else:
self.w.close() # Close window.
self.w = None # Discard reference.
def printFromSecondWindow(self):
print(self.w.text)
app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()
Instantiate the second window once in the main window constructor. self.w = AnotherWindow (self)
When creating an instance of the second window, self.w = AnotherWindow (self) - self is passed as a parent, so that when the main window is closed, the second window also closes.
To get text from a QLineEdit widget - apply QString text() const, more https://doc.qt.io/qt-5/qlineedit.html#text-prop
You did not show the method printFromSecondWindow in which, as I understand it, you wanted to show what you intended.
Try it:
import sys
from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.Qt import *
class AnotherWindow(QMainWindow):
def __init__(self, parent=None):
super(AnotherWindow, self).__init__(parent)
self.widgetf = QWidget()
self.setCentralWidget(self.widgetf)
# self.resize(1200, 600)
self.text = "basetext"
self.layoutf = QFormLayout(self.widgetf)
self.buttonf = QPushButton("get text")
# self.buttonf.clicked.connect(lambda: self.getText) # ??? lambda
self.buttonf.clicked.connect(self.getText)
self.line = QLineEdit()
self.layoutf.addRow(self.buttonf,self.line)
def getText(self):
print(self.line.text()) # ! .text()
self.text = self.line.text() # ! .text()
self.close()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.widget = QWidget()
self.setCentralWidget(self.widget)
# ? self.w = None # No external window yet.
self.button = QPushButton("Push for Window")
self.button.clicked.connect(self.show_new_window)
self.button1 = QPushButton("Push ")
self.button1.clicked.connect(self.printFromSecondWindow)
self.mainLayout = QGridLayout(self.widget)
self.mainLayout.addWidget(self.button, 0, 0)
self.mainLayout.addWidget(self.button1, 0, 1)
self.w = AnotherWindow(self) # +++
def show_new_window(self):
# if self.w is None:
# self.w = AnotherWindow()
self.w.show() # !
# else:
# self.w.close() # Close window.
# self.w = None # Discard reference.
def printFromSecondWindow(self): # +++
print(self.w.text)
if __name__ == '__main__':
app = QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

pyqt closing a custom dialog in main window via mouse click

Q. is it possible, dialog closes itself and return color name just when user clicked or double clicked color item
Below is working example (hopefully to demonstrate problem). clicking on canvas area will pop up color dialog. currently user has to select color and then hit 'OK' button, where as intent is complete when user click on color. Just wanted to save user time, one bit.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic, QtMultimedia, QtMultimediaWidgets
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
colorsDict = { 'White': '0xFFFFFF','DarkGray': '0xA9A9A9','DarkSlateGray': '0x2F4F4F','LightSlateGray': '0x778899','DimGray': '0x696969','Gray': '0x808080','SlateGray': '0x708090','Black': '0x000000','DarkRed': '0x8B0000','Darkorange': '0xFF8C00','FireBrick': '0xB22222','Crimson': '0xDC143C','Salmon': '0xFA8072'}
def hexToQColor (h):
h = h.lstrip('#') # general usage safety
# h = h.lstrip('0x') # my use case
if h.find('0x') == 0:
h = h.split('0x')[1]
rgb = tuple(int(h[i:i+2], 16) for i in (0, 2 ,4))
return QColor(rgb[0],rgb[1],rgb[2])
class FfmpegColorDialog(QDialog):
"""
Custom FFMPEG Color Picker class
"""
resized = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(FfmpegColorDialog, self).__init__(parent)
# self.ui = uic.loadUi('ui/ffmpeg_colors.ui', self)
self.setWindowTitle("FFMPEG Color Picker")
self.listWidget = QListWidget()
self.readPrefs()
self.listWidget.setFlow(QListView.LeftToRight)
self.listWidget.setResizeMode(QListView.Adjust)
self.listWidget.setGridSize(QSize(32, 32))
self.listWidget.setSpacing(5)
self.listWidget.setViewMode(QListView.IconMode)
self.listWidget.itemClicked.connect(self.itemClicked)
self.listWidget.itemDoubleClicked.connect(self.itemDoubleClicked)
layout = QVBoxLayout(self)
layout.addWidget(self.listWidget)
# OK and Cancel buttons
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def readPrefs(self):
"""
reading preferences from module for Data in UI
"""
for each in colorsDict.keys():
item = colorsDict[each]
listItem = QListWidgetItem()
listItem.setToolTip(each)
listItem.setSizeHint(QSize(30, 30))
color = hexToQColor(item)
listItem.setBackground(QBrush(color))
self.listWidget.addItem(listItem)
def itemClicked(self,item):
self.listWidget.setCurrentItem(item)
# self.accept()
def itemDoubleClicked(self,item):
c = item.background().color()
self.listWidget.setCurrentItem(item)
result = self.exec_()
return(c,result==QDialog.Accepted)
def getResults(self):
if self.exec_() == QDialog.Accepted:
item = self.listWidget.currentItem()
# print (item.toolTip())
return ( item.toolTip())
else:
return None
def getUserColor(self):
return (self.listWidget.currentItem().toolTip())
#staticmethod
def getFinalColor(parent=None):
dialog = FfmpegColorDialog(parent)
result = dialog.exec_()
color = dialog.getUserColor()
return(color,result==QDialog.Accepted)
class MainWindow(QMainWindow):
central_widget = None
layout_container = None
def __init__(self):
super(MainWindow, self).__init__()
self.central_widget = QWidget()
self.layout_container = QVBoxLayout()
self.central_widget.setLayout(self.layout_container)
self.setCentralWidget(self.central_widget)
self.layout_container.addWidget(GraphicsView())
class GraphicsView(QGraphicsView):
def __init__(self):
super(GraphicsView, self).__init__()
self.scene = QGraphicsScene()
self.setScene(self.scene)
self.text = None
self.createText()
def createText(self):
self.text = QGraphicsTextItem()
font = QFont()
font.setPixelSize(40)
self.text.setFont(font)
self.text.setPlainText("Sample Text To Test")
self.scene.addItem(self.text)
def mousePressEvent(self, event):
r,ok = FfmpegColorDialog.getFinalColor()
hc = colorsDict[r]
rgb = hexToQColor(hc)
self.text.setDefaultTextColor(rgb)
if __name__ == '__main__':
app = QApplication(sys.argv)
# dia = FfmpegColorDialog()
# dia.show()
mw = MainWindow()
mw.show()
sys.exit(app.exec_())
Just connect the clicked signal of the QListWidget to the accept slot of FfmpegColorDialog:
class FfmpegColorDialog(QDialog):
"""
Custom FFMPEG Color Picker class
"""
resized = QtCore.pyqtSignal()
def __init__(self, parent=None):
super(FfmpegColorDialog, self).__init__(parent)
# ...
self.listWidget = QListWidget()
self.listWidget.clicked.connect(self.accept) # <---
# ...

Pyqt5 - Back to hidden MainWindows

I'm making a program to specify a specific area using pyqt5.
If I click on the capture button, I will hide the MainWindow and display a screen to specify the area. I want to clear the screen and return to the mainwindow by pressing the esc key. But MainWindow does not show again. How should I work it?
form_class = uic.loadUiType("prototype.ui")[0]
class MainWindow(QtWidgets.QMainWindow, form_class) :
def __init__(self):
super().__init__()
self.setupUi(self)
self.Capture_Button.clicked.connect(self.Capture_Btn_clicked)
self.CaptureWindow = CaptureWidget()
self.CaptureWindow.hide()
def Capture_Btn_clicked(self) :
self.hide()
self.CaptureWindow.close()
self.CaptureWindow.__init__()
self.CaptureWindow.show()
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
def enterEvent(self, QEvent):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.setWindowOpacity(1)
This is the class that specifies the area (some of the code is omitted).
class CaptureWidget(QtWidgets.QDialog):
def __init__(self):
super().__init__()
root = tk.Tk()
self.setupUi(self)
def setupUi(self) :
self.screen_width = root.winfo_screenwidth()
self.screen_height = root.winfo_screenheight()
self.setGeometry(0, 0, self.screen_width, self.screen_height)
self.setWindowTitle(' ')
self.begin = QtCore.QPoint()
self.end = QtCore.QPoint()
self.setWindowOpacity(0.3)
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
self.setWindowFlags(QtCore.Qt.FramelessWindowHint|QtCore.Qt.WindowStaysOnTopHint)
print('Capture the screen...')
self.is_set_region = False
self.is_mouse_click = False
self.show()
def keyPressEvent(self, event):
key = event.key()
if key == Qt.Key_Escape:
print('esc')
self.close()
elif key == Qt.Key_F1:
self.close()
self.__init__()
First of all, instead of overwriting the keyPressEvent method, it is easier to use QShortcut. On the other hand for this case it is better to create a signal that indicates when the escape key is pressed connecting it to the show method.
from PyQt5 import QtCore, QtGui, QtWidgets, uic
class CaptureWidget(QtWidgets.QDialog):
escape_pressed = QtCore.pyqtSignal()
def __init__(self):
super().__init__()
self.setupUi()
def setupUi(self):
self.setWindowOpacity(0.3)
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
self.setWindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
shorcut_scaped = QtWidgets.QShortcut(QtCore.Qt.Key_Escape, self)
shorcut_scaped.activated.connect(self.escape_pressed)
shorcut_scaped.activated.connect(self.close)
shorcut = QtWidgets.QShortcut(QtCore.Qt.Key_F1, self)
shorcut.activated.connect(self.close)
form_class, _ = uic.loadUiType("prototype.ui")
class MainWindow(QtWidgets.QMainWindow, form_class):
def __init__(self):
super().__init__()
self.setupUi(self)
self.Capture_Button.clicked.connect(self.Capture_Btn_clicked)
self.CaptureWindow = CaptureWidget()
self.CaptureWindow.escape_pressed.connect(self.show)
#QtCore.pyqtSlot()
def Capture_Btn_clicked(self):
self.hide()
self.CaptureWindow.showFullScreen()
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CrossCursor))
def enterEvent(self, QEvent):
QtWidgets.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
self.setWindowOpacity(1)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

How to scroll text in QTextEdit automatically (animational effect)?

I would like to ask how to make the text in QTextEdit scoll, to achieve an animational effect. The animational effect should be something like what in the video shows: https://www.youtube.com/watch?v=MyeuGdXv4XM
With PyQt I want to get this effect:
The text should be scolled automatically at a speed of 2 lines/second downwards, till it reaches the end and stops.
In my code below, when the button is clicked, the text is shown in QTextEdit-Widget. The text is very long, so that the scroll bar is shown.
My Problem:
I dont know how to make the animation effect. Thus I would like to ask your help to correct my code.
# -*- coding: utf-8 -*-
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import sys
import time
list_longText = [" long text 1 - auto scrolling " * 1000, " long text 2 - auto scrolling " * 2000]
class Worker(QObject):
finished = pyqtSignal()
strTxt = pyqtSignal(str)
def __init__(self, parent=None):
super(Worker, self).__init__(parent)
#pyqtSlot()
def onJob(self):
for i in range(2):
self.strTxt.emit(list_longText[i])
time.sleep(2)
class MyApp(QWidget):
def __init__(self):
super(MyApp, self).__init__()
self.setFixedSize(600, 400)
self.setObjectName("window")
self.initUI()
def initUI(self):
self.txt = QTextEdit("", self)
self.btn = QPushButton("Button", self)
self.btn.clicked.connect(self.start)
self.layout = QHBoxLayout(self)
self.layout.addWidget(self.txt)
self.layout.addWidget(self.btn)
self.setLayout(self.layout)
self.show()
def start(self):
self.thread = QThread()
self.obj = Worker()
self.obj.strTxt.connect(self.showText)
self.obj.moveToThread(self.thread)
self.obj.finished.connect(self.thread.quit)
self.thread.started.connect(self.obj.onJob)
self.thread.start()
def showText(self, str):
self.txt.setText("{}".format(str))
self.autoScroll()
def autoScroll(self):
vsb = self.txt.verticalScrollBar()
if vsb.value() <= vsb.maximum():
vsb.setValue(vsb.value() + 2)
time.sleep(1)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyApp()
sys.exit(app.exec_())
Thanks very much for the help!
The task you want is not heavy, it is periodic so using a thread is inappropriate, for this task we can use QVariantAnimation.
The other part is to create a method that moves to a certain line of text for it we use QTextCursor next to findBlockByLineNumber() of QTextDocument.
And for the last one we must start moving to the last initial visible for it we use the cursorForPosition() method through the size of the viewport().
longText = "\n".join(["{}: long text - auto scrolling ".format(i) for i in range(100)])
class AnimationTextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
QTextEdit.__init__(self, *args, **kwargs)
self.animation = QVariantAnimation(self)
self.animation.valueChanged.connect(self.move)
#pyqtSlot()
def startAnimation(self):
self.animation.stop()
lines_per_second = 2
self.moveToLine(0)
p = QPoint(self.viewport().width() - 1, self.viewport().height() - 1)
cursor = self.cursorForPosition(p)
self.animation.setStartValue(cursor.blockNumber())
self.animation.setEndValue(self.document().blockCount()-1)
self.animation.setDuration(self.animation.endValue()*1000/lines_per_second)
self.animation.start()
#pyqtSlot(QVariant)
def move(self, i):
cursor = QTextCursor(self.document().findBlockByLineNumber(i))
self.setTextCursor(cursor)
class MyApp(QWidget):
def __init__(self):
super(MyApp, self).__init__()
self.setFixedSize(600, 400)
self.txt = AnimationTextEdit(self)
self.btn = QPushButton("Start", self)
self.layout = QHBoxLayout(self)
self.layout.addWidget(self.txt)
self.layout.addWidget(self.btn)
self.txt.append(longText)
self.txt.move(0)
self.btn.clicked.connect(self.txt.startAnimation)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
Update:
if you want a continuous movement you must use verticalScrollBar():
longText = "\n".join(["{}: long text - auto scrolling ".format(i) for i in range(100)])
class AnimationTextEdit(QTextEdit):
def __init__(self, *args, **kwargs):
QTextEdit.__init__(self, *args, **kwargs)
self.animation = QVariantAnimation(self)
self.animation.valueChanged.connect(self.moveToLine)
#pyqtSlot()
def startAnimation(self):
self.animation.stop()
self.animation.setStartValue(0)
self.animation.setEndValue(self.verticalScrollBar().maximum())
self.animation.setDuration(self.animation.endValue()*4)
self.animation.start()
#pyqtSlot(QVariant)
def moveToLine(self, i):
self.verticalScrollBar().setValue(i)
class MyApp(QWidget):
def __init__(self):
super(MyApp, self).__init__()
self.setFixedSize(600, 400)
self.txt = AnimationTextEdit(self)
self.btn = QPushButton("Start", self)
self.layout = QHBoxLayout(self)
self.layout.addWidget(self.txt)
self.layout.addWidget(self.btn)
self.txt.append(longText)
self.txt.moveToLine(0)
self.btn.clicked.connect(self.txt.startAnimation)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())

QMenu for QTableWidget in PySide/PyQt

here is my question details: I have these widgets - QMenuBar, QTableWidget and QToolbar. Here is my code sample:
import sys
from PySide import QtGui
class Example(QtGui.QMainWindow):
def __init__(self):
super(Example, self).__init__()
self.header_lbls = ['Name', 'Second Name', 'Surname', 'Birth Date', 'Phone Number', 'Skype', 'E-mail']
self.table = QtGui.QTableWidget(10, 7)
self.table.setHorizontalHeaderLabels(self.header_lbls)
self.setCentralWidget(self.table)
#ACTIONS
self.createActions()
#MENUBAR
self.createMenus()
#TOOLBAR
self.createToolbar()
#STATUSBAR
self.creatStatusbar()
def contextMenuEvent(self, event):
self.menu = QtGui.QMenu(self.table)
self.menu.addAction(self.aboutAct)
self.menu.exec_(QtGui.QCursor.pos())
def createActions(self):
self.exitAct = QtGui.QAction('E&xit', self, shortcut='Ctrl+Q',
statusTip='Exit the application', triggered=app.exit)
def createMenus(self):
self.menubar = self.menuBar()
self.fileMenu = self.menuBar().addMenu("&File")
self.fileMenu.addAction(self.exitAct)
def createToolbar(self):
self.toolbar = self.addToolBar('Toolbar')
self.toolbar.addAction(self.settingsAct)
self.toolbar.addSeparator()
self.toolbar.addAction(self.exitAct)
def creatStatusbar(self):
self.statusBar()
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
window = Example()
window.setGeometry(80, 80, 800, 600)
window.show()
sys.exit(app.exec_())
The question is: How make QMenu like in Microsoft Excel for example (I mean only add/delete rows/coloumns). Thanks in advance.
Use the customContextMenuRequested signal of the table's header-views:
class Example(QtGui.QMainWindow):
def __init__(self):
...
header = self.table.horizontalHeader()
header.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
header.customContextMenuRequested.connect(self.handleHeaderMenu)
def handleHeaderMenu(self, pos):
print('column(%d)' % self.table.horizontalHeader().logicalIndexAt(pos))
menu = QtGui.QMenu()
menu.addAction('Add')
menu.addAction('Delete')
menu.exec_(QtGui.QCursor.pos())

Categories

Resources