pyqt5 - error zsh: segmentation fault on Mac OS Monterey 12.4 [duplicate] - pyqt5

I am using PyQt based on Qt4. My Editor is PyCharm 2017.3 and my python version is 3.4. I am scraping some text from a website. I am trying to align that text to the center of the cell in a QTableWidget.
item = QTableWidgetItem(scraped_age).setTextAlignment(Qt.AlignHCenter)
self.tableWidget.setItem(x, 2,item)
Therefore while putting the item in the cell, I am trying to align it as per the documentation. The problem is that the data is not showing up.
It did show up when I removed setTextAlignment method as shown below
item = QTableWidgetItem(scraped_age)
self.tableWidget.setItem(x, 2,item)

This line of code:
item = QTableWidgetItem(scraped_age).setTextAlignment(Qt.AlignHCenter)
will not work properly, because it throws away the item it creates before assigning it to the variable. The variable will in fact be set to None, which is the return value of setTextAlignment(). Instead, you must do this:
item = QTableWidgetItem(scraped_age) # create the item
item.setTextAlignment(Qt.AlignHCenter) # change the alignment

This didn't work for me, and I'm not sure if it is because I'm using PyQt5 or it i did something wrong. I was trying to find something similar but for the whole table, and i finally stumbled upon something that worked and lets you center every cells or just one column at a time.
You have to use the delegate method:
#You're probably importing QtWidgets to work with the table
#but you'll also need QtCore for the delegate class
from PyQt5 import QtCore, QtWidgets
class AlignDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super(AlignDelegate, self).initStyleOption(option, index)
option.displayAlignment = QtCore.Qt.AlignCenter
After implementing this in your code, you can add the following to your main window class or wherever the table is defined:
delegate = AlignDelegate(self.tableWidget)
self.tableWidget.setItemDelegateForColumn(2, delegate) #You can repeat this line or
#use a simple iteration / loop
#to align multiple columns
#If you want to do it for all columns:
#self.tableWidget.setItemDelegate(delegate)
Know this is an old question, but hope it can help someone else.

Bit late to the party but for those of you wondering how to do this on pyqt5
table = QTableWidgetItem() #QTWidgets.QTableWidgetItem() if importing QWidget from PyQt5
table.setTextAlignment(number)
setTextAlignment takes an int for the argument (alignment). Put the number in to get the result:
0:left
1:left
2:right
3:right
4:centre

Related

Append data to a dataframe using root.after() from tkinter

first I'm going to explain what my script does, and then problem. I'm trying to automatize a task every 5 mins. This task involves pandas Tkinter and Matplotlib. I'll attach some guide code of mine to help understand this. First, I do some big task to initialize software programs (petroleum ones) to open files and then work with them. Second, I create a Treeview window and a plot window from Tkinter, then I need them to be updated every 5 mins, the Treeview is updated as expected, but the main problem is that I can't update or append some data to an empty dataframe;which is generated in every loop, need this new data to update plot every5 mins. I tried with append like in code, but it's not working, thanks in advance people.
import pandas
import tkinter as tk
## big task here
#create an empty dataframe
dfoil = pd.DataFrame(columns=[['Date','Oil Rate Cal','Oil Rate Mesu']])
root=tk.Tk
def update_item(df,df0,df01,df02):
#where df,df0,df01,df02 are dataframes are updated and are working correctly
#another big task here where i can get the desire results and i can see a treeview updating every 5 mins
#.........
#.........
#time2 comes from a working dataframe
dfoil.append({'Date':time2, 'Oil Rate Cal':dff1.iat[3,11],'Oil Rate Mesu':dff1.iat[3,12]},ignore_index=True)
root.after(1000*60*5, update_item, df,df0,df01,df02)
update_item(my_df,raiserdf,separetordf,compressorsdf)
root.mainloop
dfoil is the dataframe that is always getting empty after everyloop
You need to add inside the function:
global dfoil
This will make the dataframe global and 'exist' outside the function
Another option is at the end of the function:
return dfoil
and change the line that calls the function to:
dfoil = update_item(my_df,raiserdf,separetordf,compressorsdf)
Also the append does not occur 'inplace' so you need:
dfoil = dfoil.append({'Date':time2, 'Oil Rate Cal':dff1.iat[3,11],'Oil Rate Mesu':dff1.iat[3,12]},ignore_index=True)

pyqt5 edit taskbar under windows 10

Do someone have an example code how to manipulate the taskbar under windows 10? Like adding buttons or a taskbar progress.
Something like (self is the mainwindow)
self.task_button = QWinTaskbarButton(self)
self.task_progress = self.task_button.progress()
self.task_progress.setMinimum(0)
self.task_progress.setMaximum(100)
self.task_progress.setValue(50)
self.task_progress.resume()
self.task_progress.show()
self.task_progress.setVisible(True)
Did not worked.
This is an old question, but I couldn't easily find an answer, so for the record, this is what I had to do
Assume, this is in a class, inheriting from QMainWindow
from PyQt5.QtWinExtras import QWinTaskbarProgress, QWinTaskbarButton
...
def showEvent(self, evt):
self.taskbar_button = QWinTaskbarButton()
self.taskbar_progress = self.taskbar_button.progress()
self.taskbar_progress.setRange(0, 100)
self.taskbar_progress.show()
self.taskbar_button.setWindow(self.windowHandle())
From then on, in your application, you can manipulate the self.taskbar_progress property. Here are a few examples for reference
# Set value
self.taskbar_progress.setValue(55)
# Pause state (yellow bar)
self.taskbar_progress.pause()
# Or
self.taskbar_progress.setPaused(True)
# Stop (red bar)
self.taskbar_progress.stop()
# Run again (green bar)
self.taskbar_progress.resume()
For further reference, see the c++ reference (python versions match those)

TypeError: setCurrentWindow(): 1st arg can't be coerced to ij.gui.ImageWindow

Hi I am a very novice when it comes to scripting. I am trying to write a Jython script that will take an image that is not at the front, in imageJ, and bring it to the front. I have tried using the WindowManager but routinely run into a similar error.
TypeError: setCurrentWindow(): 1st arg can't be coerced to
ij.gui.ImageWindow
or some other form of this error. It seems as though activating an image that is not at the front shouldn't be too difficult.
Here is the code I'm using:
from ij import IJ
from ij import WindowManager as WM
titles = WM.getIDList()
WM.setCurrentWindow(titles[:1])
The WindowManager.setCurrentWindow method takes an ImageWindow object, not an int image ID. But you can look up the ImageWindow for a given ID as follows:
WM.getImage(imageID).getWindow()
Here is a working version of your code:
from ij import IJ
from ij import WindowManager as WM
print("[BEFORE] Active image is: " + IJ.getImage().toString())
ids = WM.getIDList()
win = WM.getImage(ids[-1]).getWindow()
WM.setCurrentWindow(win)
win.toFront()
print("[AFTER] Active image is: " + IJ.getImage().toString())
Notes
I renamed your titles variable to ids because the method WindowManager.getIDList() returns a list of int image IDs, not a list of String image titles.
The WM.getImage(int imageID) method needs an int, not a list. So I used ids[-1], which is the last element of the ids list, not ids[:1], which is a subarray. Of course, you could pass whichever image ID you wish.
I added the call win.toFront(), which actually brings the window to the front. Calling WM.setCurrentWindow(win) is important in that it tells ImageJ that that image is now the active image... but it will not actually raise the window, which is what it seems like you want here.

How to change right-arrow icon to access hidden menu items in QMenuBar using PyQt5?

I found no references about this in the documentation.
You cannot easily style this "extension" button because that symbol is actually an icon.
You can however access the QToolButton widget to set the icon to whatever you like. In PyQt4 you get to it with menubar.children()[0]. This should be consistent with PyQt5. Looking at the Qt5 source code, it appears that the extension icon is always created first, even if it is not shown, and the children() method returns objects in the order in which they were created (this the index of 0).
Once you have a reference to the QToolButton, you can then set the icon to whatever you like with menubar.children()[0].setIcon(my_qicon) (or similar).
Since this is one of the top items on google for modifying the "show more" icon:
Another option is to use a QToolbar. You can do the same thing except that the first child is a layout, second is the QToolButton that you want:
from qtpy import QtWidgets, QtGui
import sys
def call_back():
print('pressed')
app = QtWidgets.QApplication([])
widget = QtWidgets.QWidget()
layout = QtWidgets.QGridLayout(widget)
toolbar = QtWidgets.QToolBar()
layout.addWIdget(toolbar)
# add some actions
for i in range(10):
toolbar.addAction('test_{}'.format(i), call_back)
# change the icon, the first child is a layout!, the second it the toolbtn we want!
toolbar.children()[1].setIcon(QtGui.QIcon('path/to/image.png'))
widget.show()
app.exec_()
sys.exit()

PyGTK: dynamic label wrapping

It's a known bug/issue that a label in GTK will not dynamically resize when the parent changes. It's one of those really annoying small details, and I want to hack around it if possible.
I followed the approach at 16 software, but as per the disclaimer you cannot then resize it smaller. So I attempted a trick mentioned in one of the comments (the set_size_request call in the signal callback), but this results in some sort of infinite loop (try it and see).
Does anyone have any other ideas?
(You can't block the signal just for the duration of the call, since as the print statements seem to indicate, the problem starts after the function is left.)
The code is below. You can see what I mean if you run it and try to resize the window larger and then smaller. (If you want to see the original problem, comment out the line after "Connect to the size-allocate signal", run it, and resize the window bigger.)
The Glade file ("example.glade"):
<?xml version="1.0"?>
<glade-interface>
<!-- interface-requires gtk+ 2.16 -->
<!-- interface-naming-policy project-wide -->
<widget class="GtkWindow" id="window1">
<property name="visible">True</property>
<signal name="destroy" handler="on_destroy"/>
<child>
<widget class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">In publishing and graphic design, lorem ipsum[p][1][2] is the name given to commonly used placeholder text (filler text) to demonstrate the graphic elements of a document or visual presentation, such as font, typography, and layout. The lorem ipsum text, which is typically a nonsensical list of semi-Latin words, is a hacked version of a Latin text by Cicero, with words/letters omitted and others inserted, but not proper Latin[1][2] (see below: History and discovery). The closest English translation would be "pain itself" (dolorem = pain, grief, misery, suffering; ipsum = itself).</property>
<property name="wrap">True</property>
</widget>
</child>
</widget>
</glade-interface>
The Python code:
#!/usr/bin/python
import pygtk
import gobject
import gtk.glade
def wrapped_label_hack(gtklabel, allocation):
print "In wrapped_label_hack"
gtklabel.set_size_request(allocation.width, -1)
# If you uncomment this, we get INFINITE LOOPING!
# gtklabel.set_size_request(-1, -1)
print "Leaving wrapped_label_hack"
class ExampleGTK:
def __init__(self, filename):
self.tree = gtk.glade.XML(filename, "window1", "Example")
self.id = "window1"
self.tree.signal_autoconnect(self)
# Connect to the size-allocate signal
self.get_widget("label1").connect("size-allocate", wrapped_label_hack)
def on_destroy(self, widget):
self.close()
def get_widget(self, id):
return self.tree.get_widget(id)
def close(self):
window = self.get_widget(self.id)
if window is not None:
window.destroy()
gtk.main_quit()
if __name__ == "__main__":
window = ExampleGTK("example.glade")
gtk.main()
Here's a one-line variation on killown's solution:
label.connect('size-allocate', lambda label, size: label.set_size_request(size.width - 1, -1))
The above will make sure that the label takes on the width allocated to it, so that word-wrapping is happy.
Not sure why there's a "-1" for the width, but it seems harmless!
VMware's libview has a widget called WrapLabel which should do what you want, but it's in C++. A Python translation is available in the Meld repository (separated out from busybox.py).
example for resize and wrap the label dynamically:
EDIT:
import gtk
class DynamicLabel(gtk.Window):
def __init__(self):
gtk.Window.__init__(self)
self.set_title("Dynamic Label")
self.set_size_request(1, 1)
self.set_default_size(300,300)
self.set_position(gtk.WIN_POS_CENTER)
l = gtk.Label("Dynamic Label" * 10)
l.set_line_wrap(True)
l.connect("size-allocate", self.size_request)
vbox = gtk.VBox(False, 2)
vbox.pack_start(l, False, False, 0)
self.add(vbox)
self.connect("destroy", gtk.main_quit)
self.show_all()
def size_request(self, l, s ):
l.set_size_request(s.width -1, -1)
DynamicLabel()
gtk.main()
You can use this. Not sure where it came from originally. Create your label and then call label_set_autowrap(label)
def label_set_autowrap(widget):
"Make labels automatically re-wrap if their containers are resized. Accepts label or container widgets."
# For this to work the label in the glade file must be set to wrap on words.
if isinstance(widget, gtk.Container):
children = widget.get_children()
for i in xrange(len(children)):
label_set_autowrap(children[i])
elif isinstance(widget, gtk.Label) and widget.get_line_wrap():
widget.connect_after("size-allocate", _label_size_allocate)
def _label_size_allocate(widget, allocation):
"Callback which re-allocates the size of a label."
layout = widget.get_layout()
lw_old, lh_old = layout.get_size()
# fixed width labels
if lw_old / pango.SCALE == allocation.width:
return
# set wrap width to the pango.Layout of the labels
layout.set_width(allocation.width * pango.SCALE)
lw, lh = layout.get_size() # lw is unused.
if lh_old != lh:
widget.set_size_request(-1, lh / pango.SCALE)
In GTK 3, this is done automatically using height-for-width and width-for-height size requests.
I just wanted to share how I made Kai's solution work with PyGtk and Glade-3 using wraplabel.py.
I didn't want to have to modify Glade catalogs to get WrapLabel in Glade and I'm not sure if that would work anyway with a PyGtk component. I was however pleasantly surprised to find that simply by putting the WrapLabel class in the python environment before calling into gtk.Bilder() it will load the class as a component.
So now the only problem was to get the WrapLabels into the glade file. First I changed the names of all the labels I wanted to wrap to wlabel###, where ### is some number. Then I used a sed expression to replace the classes, but since I didn't want to add extra processing to the build system I ended up adding the following in python:
import re
import gtk
from wraplabel import WrapLabel
. . .
# Filter glade
glade = open(filename, 'r').read()
glade = re.subn('class="GtkLabel" id="wlabel',
'class="WrapLabel" id="wlabel', glade)[0]
# Build GUI
builder = gtk.Builder()
builder.add_from_string(glade)
I'm sure there are more elegant ways to do the substitution but this worked well. However, I found I had one more problem. When I opened one of the dialogs with the wrapped labels some of the text was not visible. Then when I resized the window with the mouse, even a little bit, everything would snap in to place. Some how the labels were not getting the right sizes when initialized. I fixed this with another work around. When opening one of the dialogs I run this code:
def open_dialog(self, dialog):
# Hack to make WrapLabel work
dims = dialog.get_size()
dialog.resize(dims[0] + 1, dims[1] + 1)
dialog.present()
dialog.resize(*dims)
This just sets the size one point too big, presents the window and then resets to the correct size. This way the WrapLabels get the signal to resize after the dialog layout is complete.
There is still one small glitch. When you open the dialog sometimes you can see the text snapping in to place. Otherwise, it seems to work.
NOTE 1) All the variations of calling label.set_size_request(size.width - 1, -1) on size-allocate caused the GUI to lockup for me. Probably depends on the parent widgets.
NOTE 2) Another solution is to use TextView's and disable editing, the cursor and sensitivity. However, TextViews have a different color than the background which is difficult to fix in the face of Gtk themes. The other problem with this solution is that TextViews capture mouse scroll events. This makes mouse scrolling a box with these TextViews inside it very erratic. I tried many things to solve the mouse scroll problem but never did figure it out. Otherwise using TextViews does work. So you might consider this if your text labels are not inside a scroll pane and the WrapLabel solution doesn't work for you.
I have modified the code that was in the other answers to get a callback that behaved a little better:
def on_label_size_allocate(self, label, allocation, *args):
""" Callback that re-allocates the size of a label to improve word wrap. """
layout = label.get_layout()
layout.set_width((allocation.width-20) * pango.SCALE)
_, lh = layout.get_pixel_size()
label.set_size_request(-1, lh+6)
The -20 and +6 numbers were obtained by trial and error. It would be nice to get them from somewhere in the widgets, but I couldn't find any relationship to the widgets. This makes the label resize fine both in growing and shrinking and lines are not cut.