Neither I could find a tutorial-like scheme for a resize event on QMainWindow, nor I did see any option for adding resize event in the drop-down menu at the Qt design window.
I am new to Qt. I'd like to write a slot function for a QMainWindow resize event. Is there such event? How can I do this?
There is a resize event. In order to perform custom handling of the event, you'll need to create your own resize event handler. In your case, you would need to create a class that derives from QMainWindow and reimplement the resizeEvent function. Your code would look something like this:
void MyMainWindow::resizeEvent(QResizeEvent* event)
{
QMainWindow::resizeEvent(event);
// Your code here.
}
The Qt Scribble example also has an example of overriding the resize event (though not on the main window).
This works in Qt5 with me f.e. to resize the icon in a QTableWidget:
mainWindow.h
...
private:
void resizeEvent(QResizeEvent*);
...
mainWindow.cpp
...
void mainWindow::resizeEvent(QResizeEvent*)
{
tableWidget->setIconSize(QSize(tableWidget->size()/7)); //7 or whatever number you need it to get the full icon size
}
In PyQt5 try the following:
from PyQt5 import QtWidgets as qtw
from PyQt5 import QtGui as qtg
class MainWindow(qtw.QMainWindow):
def __init__(self):
super().__init__()
self.resize(600, 600)
# your code
def resizeEvent(self, e: qtg.QResizeEvent):
# your code
Related
Recently, I want that QListWidgetItem can emit a signal, when the mouse pointer enter. Show a QStackedWidget, when leave, hide the QStackedWidget;
I defined a class My_ListWidget; in the class i override enterEvent and leaveEvent. But this is i hover the QListWidget not the QListWidgetItem, and it always show the first of the QStackedWidget.
override mouseMoveEvent and grab the QListWidgetItem under the cursor with itemAt(event.pos())
edit: instead of overriding mouseEvent you can use the signal entered which will also pass the ModelIndex of the item end then use leaveEvent to clear the stacked widget, you need to activate mouseTracking for this to work
For me, I had some problems with getting the Item via itemAt. When subclassing QListWidget, you can enable mouse tracking with setMouseTracking(True) and use itemEntered and leaveEvent
class My_ListWidgetClass(QListWidget):
def __init__(self):
QListWidget.__init__(self)
self.setMouseTracking(True)
class Main(...):
def __init__(self):
self.centralWidget.connect( self.My_ListWidgetInstance,
SIGNAL('itemEntered(QListWidgetItem *)'),
self.whenItemEntered_doThis)
self.centralWidget.connect( self.My_ListWidgetInstance,
SIGNAL('leaveEvent(QEvent *)'),
self.whenItemLeft_doThis)
def whenItemEntered_doThis(self, QLWItem):
# you can apply behavior here according
# to the QListWidgetItem given as argument
# e. g. get itemtext (itemtext = str(QLWItem.text())
def whenItemLeft_doThis(self, Event):
# executed when an item was left
# unfortunatelly I can't explain, what you
# can do with the event. I didn't need it...
I'd like to change the QStyle::PM_TabBarTabHSpace property for a PyQt application. I read the Qt document for QStyle, but I'm not sure how to set this correctly in PyQt.
Non-working code:
style = QStyleFactory.create('Cleanlooks')
style.PM_TabBarTabHSpace = 5 # 5 pixels?
app.setStyle(style)
This code runs, but it doesn't change the padding on the tabbar tabs. I tried using stylesheets to change the tabbar padding, but that ruins the graphics drawing, so that none of the default look-feel stuff gets drawn (I don't want to reimplement all the ui drawing).
I think I might need to use QProxyStyle, but I can't find any examples of how to use this in PyQt4. Edit: It seems that PyQt doesn't have QProxyStyle, as from PyQt4.QtGui import QProxyStyle fails.
Can someone please post an example of changing the value of PM_TabBarTabHSpace? Thanks.
Edit Here is a skeleton code. Changing the PM_TabBarTabHSpace value doesn't do anything. :(
from PyQt4.QtGui import (QApplication, QTabWidget, QWidget,
QStyle, QStyleFactory)
def myPixelMetric(self, option=None, widget=None):
if option == QStyle.PM_TabBarTabHSpace:
return 200 # pixels
else:
return QStyle.pixelMetric(option, widget)
style = QStyleFactory.create('Windows')
style.pixelMetric = myPixelMetric
app = QApplication('test -style Cleanlooks'.split())
# Override style
app.setStyle(style)
tab = QTabWidget()
tab.addTab(QWidget(), 'one')
tab.addTab(QWidget(), 'two')
tab.show()
app.exec_()
QStyle.pixelMetric(...) is built-in class method. You can not set via function pointing. Because, it is in C code. You can test it with adding
def myPixelMetric(self, option=None, widget=None):
print 'Debug, i am calling'
...
in your myPixelmetric function. You need to subclass Style object to achieve this. Here is an example:
class MyStyle(QCommonStyle):
def pixelMetric(self, QStyle_PixelMetric, QStyleOption_option=None, QWidget_widget=None):
if QStyle_PixelMetric == QStyle.PM_TabBarTabHSpace:
return 200
else:
return QCommonStyle.pixelMetric(self, QStyle_PixelMetric, QStyleOption_option, QWidget_widget)
app = QApplication('test -style Cleanlooks'.split())
app.setStyle(MyStyle())
This code snippet will work, but it is ugly. I prefer using stylesheets over manipulating Style.
I have a custom QWidget and I simple don't want it to show up in the taskbar. I have a QSystemTrayIcon for managing exiting/minimizing etc.
I think the only thing you need here is some sort of parent placeholder widget. If you create your widget without a parent it is considered a top level window. But if you create it as a child of a top level window it is considered a child window und doesn't get a taskbar entry per se. The parent window, on the other hand, also doesn't get a taskbar entry because you never set it visible: This code here works for me:
class MyWindowWidget : public QWidget
{
public:
MyWindowWidget(QWidget *parent)
: QWidget(parent, Qt::Dialog)
{
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QMainWindow window;
MyWindowWidget widget(&window);
widget.show();
return app.exec();
}
No taskbar entry is ever shown, if this is want you intended.
Just set Qt::SubWindow flag for widget.
If you want to show/hide the widget without ever showing it at the taskbar your might check the windowflags of that widget. I'm not 100% sure, but I think I used Qt::Dialog | Qt::Tool and Qt::CustomizeWindowHint to achieve this, but my window wasn't fully decorated too. Another thing you might keep in mind if you play with that is the exit policy of your application. Closing/Hiding the last toplevel-window will normally exit your application, so maybe you need to call QApplication::setQuitOnLastWindowClosed(false) to prevent that...
Python code to achive this:
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
class MainWindow(QWidget):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent, Qt.Tool)
window = MainWindow()
window.show()
I have some embedded QComboBox in a QTableView. To make them show by default I made those indexes "persistent editor". But now every time I do a mouse scroll on top them they break my current table selection.
So basically how can I disable mouse scrolling of QComboBox?
As I found this question, when I tried to figure out the solution to (basically) the same issue: In my case I wanted to have a QComboBox in a QScrollArea in pyside (python QT lib).
Here my redefined QComboBox class:
#this combo box scrolls only if opend before.
#if the mouse is over the combobox and the mousewheel is turned,
# the mousewheel event of the scrollWidget is triggered
class MyQComboBox(QtGui.QComboBox):
def __init__(self, scrollWidget=None, *args, **kwargs):
super(MyQComboBox, self).__init__(*args, **kwargs)
self.scrollWidget=scrollWidget
self.setFocusPolicy(QtCore.Qt.StrongFocus)
def wheelEvent(self, *args, **kwargs):
if self.hasFocus():
return QtGui.QComboBox.wheelEvent(self, *args, **kwargs)
else:
return self.scrollWidget.wheelEvent(*args, **kwargs)
which is callable in this way:
self.scrollArea = QtGui.QScrollArea(self)
self.frmScroll = QtGui.QFrame(self.scrollArea)
cmbOption = MyQComboBox(self.frmScroll)
It is basically emkey08's answer in the link Ralph Tandetzky pointed out, but this time in python.
The same can happen to you in a QSpinBox or QDoubleSpinBox. On QSpinBox inside a QScrollArea: How to prevent Spin Box from stealing focus when scrolling? you can find a really good and well explained solution to the problem with code snippets.
You should be able to disable mouse wheel scroll by installing eventFilter on your QComboBox and ignore the events generated by mouse wheel, or subclass QComboBox and redefine wheelEvent to do nothing.
c++ version of Markus ansver
class FocusWhellComboBox : public QComboBox
{
public:
explicit FocusWhellComboBox(QWidget* parent = nullptr)
: QComboBox(parent)
{
this->setFocusPolicy(Qt::StrongFocus);
}
void wheelEvent(QWheelEvent* e) override
{
if (this->hasFocus()) {
QComboBox::wheelEvent(e);
}
}
};
I want to set an image on QPushButton, and the size of QPushButton should depend on the size of the image. I am able to do this when using QLabel, but not with QPushButton.
So, if anyone has a solution, then please help me out.
What you can do is use a pixmap as an icon and then put this icon onto the button.
To make sure the size of the button will be correct, you have to reisze the icon according to the pixmap size.
Something like this should work :
QPixmap pixmap("image_path");
QIcon ButtonIcon(pixmap);
button->setIcon(ButtonIcon);
button->setIconSize(pixmap.rect().size());
QPushButton *button = new QPushButton;
button->setIcon(QIcon(":/icons/..."));
button->setIconSize(QSize(65, 65));
You can also use:
button.setStyleSheet("qproperty-icon: url(:/path/to/images.png);");
Note: This is a little hacky. You should use this only as last resort. Icons should be set from C++ code or Qt Designer.
You may also want to set the button size.
QPixmap pixmap("image_path");
QIcon ButtonIcon(pixmap);
button->setIcon(ButtonIcon);
button->setIconSize(pixmap.rect().size());
button->setFixedSize(pixmap.rect().size());
I don't think you can set arbitrarily sized images on any of the existing button classes.
If you want a simple image behaving like a button, you can write your own QAbstractButton-subclass, something like:
class ImageButton : public QAbstractButton {
Q_OBJECT
public:
...
void setPixmap( const QPixmap& pm ) { m_pixmap = pm; update(); }
QSize sizeHint() const { return m_pixmap.size(); }
protected:
void paintEvent( QPaintEvent* e ) {
QPainter p( this );
p.drawPixmap( 0, 0, m_pixmap );
}
};
You can do this in QtDesigner. Just click on your button then go to icon property and then choose your image file.
This is old but it is still useful,
Fully tested with QT5.3.
Be carreful, example concerning the ressources path :
In my case I created a ressources directory named "Ressources" in the source directory project.
The folder "ressources" contain pictures and icons.Then I added a prefix "Images" in Qt So the pixmap path become:
QPixmap pixmap(":/images/Ressources/icone_pdf.png");
JF
Just use this code
QPixmap pixmap("path_to_icon");
QIcon iconBack(pixmap);
Note that:"path_to_icon" is the path of image icon in file .qrc of your project You can find how to add .qrc file here
In case anybody needs a PyQt version of the first answer:
class PictureButton(QAbstractButton):
def __init__(self, picture, parent):
super().__init__(parent)
self.setPicture(QPixmap(picture))
def setPicture(self, picture):
self.picture = picture
self.update()
def sizeHint(self):
return self.picture.size()
def paintEvent(self, e):
painter = QPainter(self)
painter.drawPixmap(0, 0, self.picture)