User resizing PyQt widgets - python

I'm very new to PyQt and Python, so hopefully this question makes sense.
I have a QTreeView, QListView and QTextEdit set next to one another in a column like format. As a user, lets say I'd like to alter the width of one of the columns. How do I go about achieving this? If you're a user of Maya, imagine a paneLayout, this is what I'm trying to achieve.
Example:
[1][2][3]
[ 1 ][2][3]
[1][ 2 ][ 3 ]
...rather than just resizing the whole window. I hope this makes sense...!
Thanks to anyone who can help!

I'm not a Maya user so I don't know what a paneLayout is, but it sounds like what you're looking for can be achieved with a QSplitter (see here or here).
Here's a quick example:
from PyQt4.QtGui import QWidget, QApplication, QTreeView, QListView, QTextEdit, \
QSplitter, QHBoxLayout
import sys
class MainWindow(QWidget):
def __init__(self):
QWidget.__init__(self)
treeView = QTreeView()
listView = QListView()
textEdit = QTextEdit()
splitter = QSplitter(self)
splitter.addWidget(treeView)
splitter.addWidget(listView)
splitter.addWidget(textEdit)
layout = QHBoxLayout()
layout.addWidget(splitter)
self.setLayout(layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
mainWindow = MainWindow()
mainWindow.show()
sys.exit(app.exec_())

Related

How to do custom drop-down list in QGIS plugin ( PYQT ) like identify tool [duplicate]

How do I create a drop-down widget, such as a drop-down QLabel, drop-down QTextBrowser, etc.?
For example, I log information in a QTextBrowser, but I don't want it taking up space on the screen. So I want to be able to click a QToolbutton and have a scrollable QTextBrowser drop-down. (A QComboBox would work too, but I can't just add each event as a separate item - I need the text to wrap, not be elided. Thus a drop-down QTextBrowser.)
Or, for example, I want a drop-down QLabel containing a picture, etc...
Create a QWidgetAction for the drop-down widget, and add it to the tool-button's menu:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QHBoxLayout(self)
self.button = QtGui.QToolButton(self)
self.button.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.button.setMenu(QtGui.QMenu(self.button))
self.textBox = QtGui.QTextBrowser(self)
action = QtGui.QWidgetAction(self.button)
action.setDefaultWidget(self.textBox)
self.button.menu().addAction(action)
layout.addWidget(self.button)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(100, 60)
window.show()
sys.exit(app.exec_())

Stretch stopped working after parenting widget to layout pyqt

I am here with pyqt question again.
I think, this question was probably answered somewhere, but I can't phrase my problem properly in a way to find it in google, so sorry if it's duplicated the question.
I wrote simple code to show the problem I am facing.
import sys
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QHBoxLayout, QApplication, QMenu, QWidget, QPushButton
class MainWindow(QDialog):
def __init__(self):
QDialog.__init__(self)
self.mainLayout = QVBoxLayout()
self.setLayout(self.mainLayout)
self.create()
def create(self):
btn_widget_a = QWidget()
btn_layout_a = QHBoxLayout(btn_widget_a)
self.mainLayout.addWidget(btn_widget_a)
btn_a = QPushButton()
btn_layout_a.addWidget(btn_a)
btn_a.setFixedSize(60, 60)
btn_b = QPushButton()
btn_layout_a.addWidget(btn_b)
btn_b.setFixedSize(60, 60)
tool_widget = QWidget()
btn_layout_a.addWidget(tool_widget)
tool_menu= QMenu(tool_widget)
tool_menu.addMenu('Options')
btn_a.setMenu(tool_menu)
if __name__ == '__main__':
app = QApplication(sys.argv)
main = MainWindow()
main.show()
app.exec_()
Problem is this btn_layout_a.addWidget(tool_widget) when I add QMenu inside the widget in my layout, buttons don't stretch anymore when you resize your UI. Is there a way to fix it? I know that if simply delete btn_layout_a.addWidget(tool_widget) it will work properly, but thing is that unless I put it in a widget, QMenu doesn't work properly inside the software called Maya. I tried adding stretch as an argument to widget/layout and tried command addStrerch() but nothing seems to give any result. Any suggestions? Thank you!

PyQt5 QCompleter for QLineEdit crashing with no exception visible

I'm trying to use the QCompleter class for the QLineEdit to give auto completion suggestions while typing, and update the suggestions after the user enters a new text. But when I try to update the Completer with text that starts with something that is already at the completer list, it just crashes the entire app with no visible exception! Even try-except doesn't catch this error, and I can't understand what I am doing wrong...
Below is a simpler example of my code: it is a simple "echo" console application that gets commands from QLineEdit (input text box) and writing it to QTextBrowser (output text box). When entering entirely new "command" (text) it works fine, and being added to the completer, so next time I can see it. But if the new text starts similar to other words in the completer list, choosing it crashes the entire GUI app with no exception visible, not even when I'm running in debug mode...
Please see my example below, and try writing at the upper text box options like: a, aa, aaa (that start similar to completer already word: aaa1)
What am I doing wrong??
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QMainWindow, QVBoxLayout, QLineEdit, QTextBrowser, QCompleter
class MainWindow(QMainWindow):
def __init__(self):
QMainWindow.__init__(self)
self.setWindowTitle('console')
self.setGeometry(10, 50, 500, 800)
# Create text box for input
self.consoleCommandLineEdit = QLineEdit(self)
self.consoleCommandLineEdit.setFixedHeight(25)
self.consoleCommandLineEdit.editingFinished.connect(self.gotConsoleCommand)
self.completerCommands = ['aaa1','aaa2','aaa3'] # initial completer list
completer = QCompleter(self.completerCommands)
self.consoleCommandLineEdit.setCompleter(completer)
# Create text box for output
self.consoleViewer = QTextBrowser(self)
self.consoleViewer.setLineWrapMode(QTextBrowser.NoWrap)
widget = QWidget(self)
self.setCentralWidget(widget)
self.vlay = QVBoxLayout(widget)
self.vlay.addWidget(self.consoleCommandLineEdit)
self.vlay.addWidget(self.consoleViewer)
def gotConsoleCommand(self):
cmd = self.consoleCommandLineEdit.text()
self.consoleCommandLineEdit.setText('')
self.sendCommandToConsole(cmd)
def sendCommandToConsole(self,cmd):
self.consoleViewer.append(cmd) # add cmd to output box
if cmd not in self.completerCommands: # if the command is new, add it to the completer
self.completerCommands.append(cmd) # 1. add the new text to the list we have
completer = QCompleter(self.completerCommands) # 2. create a new completer object
self.consoleCommandLineEdit.setCompleter(completer) # 3. set the new completer as the LineEdit completer
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
I have not yet found the cause of the problem but a better solution than creating a new QCompleter every time you need to add a new text. In this case it is better to use a model to store the texts that is the basis of the QCompleter information.
import sys
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtWidgets import (
QApplication,
QWidget,
QMainWindow,
QVBoxLayout,
QLineEdit,
QTextBrowser,
QCompleter,
)
class MainWindow(QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setWindowTitle("console")
self.setGeometry(10, 50, 500, 800)
# Create text box for input
self.consoleCommandLineEdit = QLineEdit()
self.consoleCommandLineEdit.setFixedHeight(25)
self.consoleCommandLineEdit.editingFinished.connect(self.gotConsoleCommand)
self.model = QStandardItemModel()
self.model.appendRow([QStandardItem(text) for text in ("aaa1", "aaa2", "aaa3")])
completer = QCompleter(self.model, self)
self.consoleCommandLineEdit.setCompleter(completer)
# Create text box for output
self.consoleViewer = QTextBrowser(lineWrapMode=QTextBrowser.NoWrap)
widget = QWidget()
self.setCentralWidget(widget)
vlay = QVBoxLayout(widget)
vlay.addWidget(self.consoleCommandLineEdit)
vlay.addWidget(self.consoleViewer)
def gotConsoleCommand(self):
cmd = self.consoleCommandLineEdit.text()
self.consoleCommandLineEdit.clear()
self.sendCommandToConsole(cmd)
def sendCommandToConsole(self, cmd):
self.consoleViewer.append(cmd) # add cmd to output box
if not self.model.findItems(cmd):
self.model.appendRow(QStandardItem(cmd))
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWin = MainWindow()
mainWin.show()
sys.exit(app.exec_())
Perhaps something that helps us understand the problem is that if you add a parent to QCompleter the problem does not happen: completer = QCompleter(self.completerCommands, self)
but I stress: the best solution is to use a model.

how to sort the items in QListWidget by drop and drag

I am newer to pyqt, I am using it to write some GUI, could anybody please tell me how to sort the items in QListWidget by drop and drag?
thanks in advance
QListWidget inherits from QAbstractItemView. You can use the QAbstractItemView.setDragDropMode() and set it to QAbstractItemView.InternalMove if you'd like to be able to change the order of your items with drag & drop.
Here's the relevent section of the documentation.
Here's a quick example showing it in action:
import sys
from PyQt4.QtGui import QApplication, QWidget, \
QVBoxLayout, QListWidget, QAbstractItemView
class Widget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.widget_layout = QVBoxLayout()
# Create ListWidget and add 10 items to move around.
self.list_widget = QListWidget()
for x in range(1, 11):
self.list_widget.addItem('Item {:02d}'.format(x))
# Enable drag & drop ordering of items.
self.list_widget.setDragDropMode(QAbstractItemView.InternalMove)
self.widget_layout.addWidget(self.list_widget)
self.setLayout(self.widget_layout)
if __name__ == '__main__':
app = QApplication(sys.argv)
widget = Widget()
widget.show()
sys.exit(app.exec_())

Qt/PyQt: How do I create a drop down widget, such as a QLabel, QTextBrowser, etc.?

How do I create a drop-down widget, such as a drop-down QLabel, drop-down QTextBrowser, etc.?
For example, I log information in a QTextBrowser, but I don't want it taking up space on the screen. So I want to be able to click a QToolbutton and have a scrollable QTextBrowser drop-down. (A QComboBox would work too, but I can't just add each event as a separate item - I need the text to wrap, not be elided. Thus a drop-down QTextBrowser.)
Or, for example, I want a drop-down QLabel containing a picture, etc...
Create a QWidgetAction for the drop-down widget, and add it to the tool-button's menu:
from PyQt4 import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
layout = QtGui.QHBoxLayout(self)
self.button = QtGui.QToolButton(self)
self.button.setPopupMode(QtGui.QToolButton.MenuButtonPopup)
self.button.setMenu(QtGui.QMenu(self.button))
self.textBox = QtGui.QTextBrowser(self)
action = QtGui.QWidgetAction(self.button)
action.setDefaultWidget(self.textBox)
self.button.menu().addAction(action)
layout.addWidget(self.button)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Window()
window.resize(100, 60)
window.show()
sys.exit(app.exec_())

Categories

Resources