Qt - subclassing to provide an alternative view for a text widget? - qt

Currently, I am in the design phase of a Qt widget like what one would see in a typical hex editor. It seemed simple enough to begin with, but as I dig into its implementation details I’m having some confusion.
Basically, the widget would consist of 3 core components: It will inherit QAbstractScrollArea or QScrollArea to provide scrolling and, in the viewport margin, it will display the file offset of each line. Then there will be two text editors; one with the hexadecimal value of each byte of the file, and one with the plaintext character representation.
I, of course, first checked qt-apps.org for any existing widgets, but a search for “hex” only returned QHexEdit and qPHexEditor, neither of which are very complete. I then considered creating a widget completely from scratch as they had, but felt like there should be a more elegant solution. Qt already has much text-editor functionality built into QTextEdit and QPlainTextEdit; why reinvent the wheel?
Now, while the “plaintext view” would be as simple as using a QPlainTextEdit with a fixed-width font and a width of 16 characters, the “hex view” is giving me a headache. I’ve been poring over QTextEdit, QAbstractTextDocumentLayout, etc., trying to figure out a way to present the desired appearance. For those who have never used a hex editor, it should function like so: – Using a fixed-width font, widget should be the width of 47 characters – Widget should display 2 hexadecimal characters per byte, with a blank space between bytes—-16 bytes per line
Since that thought, I’ve been trying to figure out how to subclass any related classes to provide the desired formatting. Unfortunately, the text editing classes don’t seem to follow the model/view framework as closely as I’d hoped, so deriving a new “view” for it doesn’t seem easy. Ideally, the widget would function like so:
One document/model for both the “hex” and “plaintext” views. Editing either view would adjust this model and update the other view appropriately. Signals/Slots at its best.
Because QTextEdit and QPlainTextEdit already provide much of the functionality needed (visible cursor, selections, undo/redo, native look and feel, etc), it would be ideal to re-use this.
So, does anyone have any recommendations? I appreciate any input on this.

QHexEdit2 is a quite complete editor widget for binary data. It can edit very big files, is available for Qt4, Qt5, PyQt4, PyQt4 with python 2 and 3.
see https://github.com/Simsys/qhexedit2

Related

Zooming a view in PyQt?

I have a simple to do tree application that displays a QTreeView inside of a QMainWindow. I want to give the user the ability to change the magnification level of the content (using a spinbox most likely), but without actually changing the underlying font size of the text.
Is there a way to do this without changing my whole app to a QGraphicsScene? The app is just showing a good-old fashioned tree with text, no graphics or anything fancy other than wanting to change the magnification of the view; hence, I am thinking that switching to a graphics scene would be overkill.
Or, am I wrong, and switching to a graphics scene is the only simple way to do it?
Note a trimmed down version of the app is at Code Review. It contains a SSCCE, but is a bit long to post here.
In a site discussing how to put widgets on a scene, trolltech wrote (emphasis added):
I myself and several other Trolls’ve spent some time researching this
topic [how to embed a widget in a QGraphicsScene]. It’s not trivial;
most solutions to embedding widgets into a scene end up with several
serious drawbacks. That’s also why Qt doesn’t have any off-the-shelf
solution to this.
Widgets cannot be scaled or rotated, but graphics items can.
This suggests I cannot perform, in a simple way, the operations I want to on my QWidget by itself. That is, perhaps I need to add it to a scene, which is what I was trying to avoid. If that is the answer, then I'll accept it and start a new question if I get stuck doing that.
Note I just found this question, which is pretty much a duplicate, and does not have an (accepted) answer.
Related content
http://www.qtcentre.org/threads/62745-Zoom-a-view
QTableView Zoom In/Out
Drawing widgets (such as buttons) over QGraphicsView
QGraphicsView Zooming in and out under mouse position using mouse wheel
https://forum.qt.io/topic/15308/qgraphicsview-zooming-with-qslider
https://wiki.qt.io/Smooth_Zoom_In_QGraphicsView
As suggested by the docs quoted from trolltech in the original question, there is no built-in method to zoom on a view.
If the goal is to avoid the use of QGraphicsViews, the simplest way to separate the size of the font on the screen, versus the size of the font saved or printed, is to basically have two fonts. One to be displayed on the screen you can call 'zoom', versus the other to be saved/printed and call that 'font size'.
I got this idea from qtcentre (in a post I added to the original post too):
http://www.qtcentre.org/threads/62745-Zoom-a-view

How to print a QQuickView's contents to PDF?

I'm upgrading some Qt (C++ & QML) code from Qt4.8 to Qt5.1.
The Qt4.8 code is a trivial C++ "QML viewer" app subclassing a QDeclarativeView, and a bunch of QML.
It's been easy enough to change this to use Qt5/QtQuick2's QQuickView except for one thing:
The Qt4.8 app has a method for printing to PDF:
void MyQMLViewer::printToPDF(const QString& filename) const {
QPrinter printer(QPrinter::HighResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setPageSize(QPrinter::A3);
printer.setOutputFileName(filename);
printer.setOrientation(QPrinter::Landscape);
QPainter painter(&printer);
render(&painter);
}
There were a few "environment" changes needed for Qt5.1 to get a QPrinter (ie add QT += printsupport to the project .pro file and #include <QtPrintSupport>), but there seems to be a more fundamental problem that QQuickView doesn't provide anything which is obviously compatible with the QGraphicsView/QPainter/QPaintDevice world of QPrinter (specifically, QQuickView has no render method, and all the drawing/painting/rendering-related methods it does have seem very tied up with OpenGL).
Any suggestions for how to best obtain high-quality PDF output from a QQuickView ?
(Note that I am not simply looking to screenshot the view; with QDeclarativeView, the code above generates PDFs with much better resolution even than the app fullscreened on my largest monitor).
I see the "QDeclarativeItem and QDeclarativeView" section of the "Porting QML Applications to Qt 5" guide does mention the loss of QGraphicsView-specific functionality, but doesn't offer any solutions (although it does mention workrounds for the case of items with custom QPainter-based rendering being bought into the new regime).
Update with some additional background info: an example of a PDF printed from QDeclarativeView using the above code can be found here. There's a png of the same view on a decent size monitor here. (This is actually the last slide in a series of slides; it's actually a gallery of the previous slides which bounces each slide onto the screen; if I had the time I'd look into the feasibility of the gallery being the only thing and transforming each scattered slide into view for a Prezi-style presentation; suspect QDeclarative isn't really performant enough though, which is one reason for wanting to get onto QtQuick2+Qt5.2's new scene graph stuff). Anyway, If you zoom the PDF up to 100% you'll see the text is... well it's better than anything a sanely sized image file will manage I think, although the sloping text baselines perhaps look a little uneven. There is also an issue with opacity values not being represented in the PDF (so the drop shadows and "bubbles" come out solid); another one of my motivations for trying for a QtQuick2 version was actually to see if translucent elements were dealt with any better. I assume the PDF just contains rasterized (or maybe vector outlines) of all the elements as utilities like "pdftotext" can't extract anything from it. I don't know enough about PDF tools to know how to inspect the internal structure of the thing but I assume there's some hierarchy there and the QML element tree is all laid out using a similar structure of nested transforms to the QML. Just for comparison and the sort of richness I'm potentially working towards here's a poster I did with LaTeX/Beamerposter; I find Beamerposter's rigid block structure rather limiting (and fiddly) compared with the possibilities QML seems to offer though. BTW, another thing on my wishlist/todolist is a QML element which can render LaTeX source, math and all, just to get the best of both worlds.
Update: Recent Qt blog post on all the backend changes in Qt5.8 has a comment linking to this Qt issue to use the new possibility of QPainter-rendered QtQuick scenes to render PDFs.
At the moment, there is no code in Qt that supports rendering of a scene graph to a pdf. The underlying data that is used to render Qt Quick 2 is held in the scene graph. As Laszlo suggests, you'd need to iterate the scene graph and generate PDF primitives. There's some impedance mismatch there, but it should be doable with some sweat. I think a proof of concept could be small enough to fit here, so I'll see how easy it could be :)
If you really want a PDF, you currently have no choice but to render it to a large image at 300dpi and wrap that in a PDF. The image doesn't have to be large if the poster has large areas of solid color. PDF can do do TIFF encoding and also JPEG encoding.

trying to make a bitmap editor in qt

I want to make a program using qt.
I have to make a bitmap editor for special purposes.
I had been looking widgets that could allow me to get this task done, one of them is QGraphicsView with QGraphicsScene.
As expected, I want my program to have many features.
They are listed below:
Exporting to image formats such as .bmp.
Support for clipboard, copy and paste. I hope this clipboard can be compatible with other similar programs.
The image must have a resolution. I mean the pixels of the screen can be bigger than the pixels of the image and vice-versa.
Selecting squared areas.
So, what I need to know is if I am using the correct widget. If not, which widget can I use? which are the member functions of the widget that I need to know?
There several ways to achieve what you want, but as your question is too broad, I would suggest looking at the Qt Scribble example and come back with specific questions relating to what it doesn't do.
The link suggested previously was replaced with a new one that points to the corresponding Qt 5 example.

QT - How to synchronize data between two widgets?

I have a QT program with a custom widget that I'm implementing. This widget is an Hexeditor, and it's already functional.
But now I want to put on the window another instance of the same Hexeditor, and I want to synchronize the data between them, so if I change a byte in one Hexeditor, the same byte is automatically changed on the other Hexeditor.
What is the best solution for this problem? What are my options? Sometimes the files can be very big, so I'm trying to find the best solution.
This is a general question, and probably is valid for other text widgets.
Thanks
I would use the very good MVC architecture widgets in Qt.
As a hexeditor is generally laid out as a table, I would use QAbstractTableModel to actually store the hex data, and then QTableView to display the data. You can then have an arbitrary mount of hex editors connected to the same model and all will be synchronised automatically. You will also have to modify a QStyledItemDelegate to provide hex-only editing in the view, but that's really straightforward.

Using QT to build a WYSIWYG Editor for a Custom Markup Language

I'm new to QT, and am trying to figure out the best means of creating a WYSIWYG editor widget for a custom markup language that displays simple text, images, and links. I need to be able to propagate changes from the WYSIWYG editor to the custom markup representation.
As a concrete example of the problem domain, imagine that the custom markup might have a "player" tag which contains a player name and a team name. The markup could look like this:
Last week, <player id="1234"><name>Aaron Rodgers</name><team>Packers</team></player> threw a pass.
This text would display in the editor as:
Last week, Aaron Rodgers of the Packers threw a pass.
The player name and the team name would be editable directly within the editor in standard WYSIWYG fashion, so that my users do not have to learn any markup. Also, when the player name is moused-over, a details pop-up will appear about that player, and similarly for the team.
With that long introduction, I'm trying to figure out where to start with QT. It seems that the most logical option would be the Rich Text API using a QTextDocument. This approach seems less than ideal given the limitations of a QTextDocument:
I can't figure out how to capture navigation events from clicking on links.
Following links on click seems to only be enabled when the QTextEdit is readonly.
Custom objects that implement QTextObjectInterface are ignored in copy-and-paste operations
Any HTML-based markup that is passed to it as Rich Text is retranslated into a series of span tags and lots of other junk, making it extremely difficult to propagate changes from the editor back to the original custom markup.
A second option appears to be QWebKit, which allows for live editing of HTML5 markup, so I could specify a two-way translation between the custom markup and HTML5. I'm not clear on how one would propagate changes from the editor back to the original markup in real-time without re-translating the entire document on every text change. The QWebKit solutions looks like awfully bulky to me (Learning WebKit along with QT) to what should be a relatively simple problem.
I have also considered implementing the WYSIWYG with a custom class using native QT containers, labels, images, and other widgets manually. This seems like the most flexible approach, and the one most likely not to run into unresolvable problems. However, I'm pretty sure that implementing all the details of a normal text editor (selecting text, font changes, cut-and-paste support, undo/redo, dragging of objects, cursor placement, etc.) will be incredibly time consuming.
So, finally, my question: are there any QT gurus out there with some advice on where to start with this sort of project?
BTW, I am using QT because the application is a desktop application that needs platform independence.
Given that I got no advice here, I decided to go with the QTextEdit approach, although I'm actually using a QTextBrowser that is set to be editable so that I can capture link navigation events. I will be using QTextCharFormat's with the link names set to unique identifiers in order to convert from the QTextEdit back to the custom markup. The QTextEdit supports images already, so I won't have to deal with those.
I think I will hit the biggest roadblocks with the fact that I need to be able to insert/grow/shrink tables whose cells can have Excel-style functionality. I have not yet figured that whole process out.

Resources